From d898f4af5666868630381c276f6e6cb8d1238b80 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Tue, 25 Nov 2025 12:21:55 -0800 Subject: [PATCH 001/119] annotated List.java --- .../share/classes/java/util/List.java | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 600761fb6c69..88e006836ccc 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -33,6 +33,11 @@ import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -174,7 +179,7 @@ public interface List extends Collection { * @return the number of elements in this list */ @Pure - @NonNegative int size(@GuardSatisfied List this); + @NonNegative int size(@UnknownModifiability @GuardSatisfied List this); /** * Returns {@code true} if this list contains no elements. @@ -183,7 +188,7 @@ public interface List extends Collection { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied List this); + boolean isEmpty(@UnknownModifiability @GuardSatisfied List this); /** * Returns {@code true} if this list contains the specified element. @@ -202,7 +207,7 @@ public interface List extends Collection { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@GuardSatisfied List this, @UnknownSignedness Object o); + boolean contains(@UnknownModifiability @GuardSatisfied List this, @UnknownSignedness Object o); /** * Returns an iterator over the elements in this list in proper sequence. @@ -210,7 +215,7 @@ public interface List extends Collection { * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty List this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List this); /** * Returns an array containing all of the elements in this list in proper @@ -229,7 +234,7 @@ public interface List extends Collection { * @see Arrays#asList(Object[]) */ @SideEffectFree - @PolyNull @PolySigned Object[] toArray(List<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(@UnknownModifiability List<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this list in @@ -271,7 +276,7 @@ public interface List extends Collection { * @throws NullPointerException if the specified array is null */ @SideEffectFree - @Nullable T[] toArray(@PolyNull T[] a); + @Nullable T[] toArray(@UnknownModifiability List this, @PolyNull T[] a); // Modification Operations @@ -301,7 +306,7 @@ public interface List extends Collection { @ReleasesNoLocks @SideEffectsOnly("this") @EnsuresNonEmpty("this") - boolean add(@GuardSatisfied List this, E e); + boolean add(@Modifiable @GuardSatisfied List this, E e); /** * Removes the first occurrence of the specified element from this list, @@ -325,7 +330,7 @@ public interface List extends Collection { * is not supported by this list */ @SideEffectsOnly("this") - boolean remove(@GuardSatisfied @Shrinkable List this, @UnknownSignedness Object o); + boolean remove(@Modifiable @GuardSatisfied @Shrinkable List this, @UnknownSignedness Object o); // Bulk Modification Operations @@ -349,7 +354,7 @@ public interface List extends Collection { * @see #contains(Object) */ @Pure - boolean containsAll(@GuardSatisfied List this, Collection c); + boolean containsAll(@UnknownModifiability @GuardSatisfied List this, Collection c); /** * Appends all of the elements in the specified collection to the end of @@ -374,7 +379,7 @@ public interface List extends Collection { */ @SideEffectsOnly("this") @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@GuardSatisfied List this, Collection c); + boolean addAll(@Modifiable @GuardSatisfied List this, Collection c); /** * Inserts all of the elements in the specified collection into this @@ -405,7 +410,7 @@ public interface List extends Collection { */ @SideEffectsOnly("this") @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); + boolean addAll(@Modifiable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); /** * Removes from this list all of its elements that are contained in the @@ -425,7 +430,7 @@ public interface List extends Collection { * @see #remove(Object) * @see #contains(Object) */ - boolean removeAll(@GuardSatisfied @Shrinkable List this, Collection c); + boolean removeAll(@Modifiable @GuardSatisfied @Shrinkable List this, Collection c); /** * Retains only the elements in this list that are contained in the @@ -447,7 +452,7 @@ public interface List extends Collection { * @see #remove(Object) * @see #contains(Object) */ - boolean retainAll(@GuardSatisfied @Shrinkable List this, Collection c); + boolean retainAll(@Modifiable @GuardSatisfied @Shrinkable List this, Collection c); /** * Replaces each element of this list with the result of applying the @@ -478,7 +483,7 @@ public interface List extends Collection { * (optional) * @since 1.8 */ - default void replaceAll(UnaryOperator operator) { + default void replaceAll(@Modifiable List this, UnaryOperator operator) { Objects.requireNonNull(operator); final ListIterator li = this.listIterator(); while (li.hasNext()) { @@ -546,7 +551,7 @@ default void replaceAll(UnaryOperator operator) { * @since 1.8 */ @SuppressWarnings({"unchecked", "rawtypes"}) - default void sort(Comparator c) { + default void sort(@Modifiable List this, Comparator c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator i = this.listIterator(); @@ -563,7 +568,7 @@ default void sort(Comparator c) { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ - void clear(@GuardSatisfied @Shrinkable List this); + void clear(@Modifiable @GuardSatisfied @Shrinkable List this); // Comparison and hashing @@ -583,7 +588,7 @@ default void sort(Comparator c) { * @return {@code true} if the specified object is equal to this list */ @Pure - boolean equals(@GuardSatisfied List this, @Nullable Object o); + boolean equals(@UnknownModifiability @GuardSatisfied List this, @Nullable Object o); /** * Returns the hash code value for this list. The hash code of a list @@ -603,7 +608,7 @@ default void sort(Comparator c) { * @see #equals(Object) */ @Pure - int hashCode(@GuardSatisfied List this); + int hashCode(@UnknownModifiability @GuardSatisfied List this); // Positional Access Operations @@ -617,7 +622,7 @@ default void sort(Comparator c) { * ({@code index < 0 || index >= size()}) */ @Pure - E get(@GuardSatisfied List this, @IndexFor({"this"}) int index); + E get(@UnknownModifiability @GuardSatisfied List this, @IndexFor({"this"}) int index); /** * Replaces the element at the specified position in this list with the @@ -637,7 +642,7 @@ default void sort(Comparator c) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ - E set(@GuardSatisfied List this, @IndexFor({"this"}) int index, E element); + E set(@Modifiable @GuardSatisfied List this, @IndexFor({"this"}) int index, E element); /** * Inserts the specified element at the specified position in this list @@ -660,7 +665,7 @@ default void sort(Comparator c) { */ @ReleasesNoLocks @SideEffectsOnly("this") - void add(@GuardSatisfied List this, @IndexOrHigh({"this"}) int index, E element); + void add(@Modifiable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, E element); /** * Removes the element at the specified position in this list (optional @@ -676,7 +681,7 @@ default void sort(Comparator c) { * ({@code index < 0 || index >= size()}) */ @ReleasesNoLocks - E remove(@GuardSatisfied @Shrinkable List this, @IndexFor({"this"}) int index); + E remove(@Modifiable @GuardSatisfied @Shrinkable List this, @IndexFor({"this"}) int index); // Search Operations @@ -699,7 +704,7 @@ default void sort(Comparator c) { * (optional) */ @Pure - @GTENegativeOne int indexOf(@GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); + @GTENegativeOne int indexOf(@UnknownModifiability @GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns the index of the last occurrence of the specified element @@ -719,7 +724,7 @@ default void sort(Comparator c) { * (optional) */ @Pure - @GTENegativeOne int lastIndexOf(@GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); + @GTENegativeOne int lastIndexOf(@UnknownModifiability @GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); // List Iterators @@ -731,7 +736,7 @@ default void sort(Comparator c) { * @return a list iterator over the elements in this list (in proper * sequence) */ - @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List this); /** * Returns a list iterator over the elements in this list (in proper @@ -748,7 +753,7 @@ default void sort(Comparator c) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index > size()}) */ - @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); // View @@ -787,7 +792,7 @@ default void sort(Comparator c) { * fromIndex > toIndex}) */ @SideEffectFree - @PolyGrowShrink List subList(@GuardSatisfied @PolyGrowShrink List this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex); + @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink List this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex); /** * Creates a {@link Spliterator} over the elements in this list. @@ -843,7 +848,7 @@ default Spliterator spliterator() { * @since 9 */ @SuppressWarnings("unchecked") - static List of() { + static @Unmodifiable List of() { return (List) ImmutableCollections.EMPTY_LIST; } @@ -859,7 +864,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1) { + static @Unmodifiable @NonEmpty List of(E e1) { return new ImmutableCollections.List12<>(e1); } @@ -876,7 +881,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2) { + static @Unmodifiable @NonEmpty List of(E e1, E e2) { return new ImmutableCollections.List12<>(e1, e2); } @@ -894,7 +899,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3); } @@ -913,7 +918,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4); } @@ -933,7 +938,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4, E e5) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5); } @@ -954,7 +959,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6); } @@ -977,7 +982,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7); } @@ -1001,7 +1006,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7, e8); } @@ -1026,7 +1031,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7, e8, e9); } @@ -1052,7 +1057,7 @@ static List of() { * * @since 9 */ - static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { + static @Unmodifiable @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } @@ -1084,7 +1089,7 @@ static List of() { */ @SafeVarargs @SuppressWarnings("varargs") - static @PolyNonEmpty List of(E @PolyNonEmpty... elements) { + static @Unmodifiable @PolyNonEmpty List of(E @PolyNonEmpty... elements) { switch (elements.length) { // implicit null check of elements case 0: @SuppressWarnings("unchecked") @@ -1115,7 +1120,7 @@ static List of() { * @throws NullPointerException if coll is null, or if it contains any nulls * @since 10 */ - static @PolyNonEmpty List copyOf(@PolyNonEmpty Collection coll) { + static @Unmodifiable @PolyNonEmpty List copyOf(@UnknownModifiability @PolyNonEmpty Collection coll) { return ImmutableCollections.listCopy(coll); } } From 10fef490a4bba1d6c7f0c5890568ddaae272f626 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Dec 2025 00:22:31 -0800 Subject: [PATCH 002/119] annotated map.java, along with initialization of HashMap, ArrayList, LinkedHashMap --- .../share/classes/java/util/ArrayList.java | 10 +- .../share/classes/java/util/HashMap.java | 11 ++- .../classes/java/util/LinkedHashMap.java | 11 ++- .../share/classes/java/util/List.java | 2 +- .../share/classes/java/util/Map.java | 92 ++++++++++--------- 5 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index fe87ea029a49..a2832c1c478a 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -30,6 +30,10 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -175,7 +179,7 @@ public class ArrayList extends AbstractList * is negative */ @SideEffectFree - public ArrayList(@NonNegative int initialCapacity) { + public @Modifiable ArrayList(@NonNegative int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { @@ -190,7 +194,7 @@ public ArrayList(@NonNegative int initialCapacity) { * Constructs an empty list with an initial capacity of ten. */ @SideEffectFree - public ArrayList() { + public @Modifiable ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } @@ -203,7 +207,7 @@ public ArrayList() { * @throws NullPointerException if the specified collection is null */ @SideEffectFree - public @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index b6fbd742f4b1..87b3ba533513 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -27,6 +27,9 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -456,7 +459,7 @@ static final int tableSizeFor(int cap) { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public HashMap(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable HashMap(@NonNegative int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); @@ -476,7 +479,7 @@ public HashMap(@NonNegative int initialCapacity, float loadFactor) { * @param initialCapacity the initial capacity. * @throws IllegalArgumentException if the initial capacity is negative. */ - public HashMap(@NonNegative int initialCapacity) { + public @Modifiable HashMap(@NonNegative int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } @@ -484,7 +487,7 @@ public HashMap(@NonNegative int initialCapacity) { * Constructs an empty {@code HashMap} with the default initial capacity * (16) and the default load factor (0.75). */ - public HashMap() { + public @Modifiable HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted } @@ -497,7 +500,7 @@ public HashMap() { * @param m the map whose mappings are to be placed in this map * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty HashMap(@PolyNonEmpty Map m) { + public @Modifiable @PolyNonEmpty HashMap(@PolyNonEmpty Map m) { this.loadFactor = DEFAULT_LOAD_FACTOR; putMapEntries(m, false); } diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 4b66d66c45c6..7eb7860ed1e1 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -359,7 +360,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); accessOrder = false; } @@ -371,7 +372,7 @@ public LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { * @param initialCapacity the initial capacity * @throws IllegalArgumentException if the initial capacity is negative */ - public LinkedHashMap(@NonNegative int initialCapacity) { + public @Modifiable LinkedHashMap(@NonNegative int initialCapacity) { super(initialCapacity); accessOrder = false; } @@ -380,7 +381,7 @@ public LinkedHashMap(@NonNegative int initialCapacity) { * Constructs an empty insertion-ordered {@code LinkedHashMap} instance * with the default initial capacity (16) and load factor (0.75). */ - public LinkedHashMap() { + public @Modifiable LinkedHashMap() { super(); accessOrder = false; } @@ -394,7 +395,7 @@ public LinkedHashMap() { * @param m the map whose mappings are to be placed in this map * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty LinkedHashMap(@PolyNonEmpty Map m) { + public @Modifiable @PolyNonEmpty LinkedHashMap(@PolyNonEmpty Map m) { super(); accessOrder = false; putMapEntries(m, false); @@ -411,7 +412,7 @@ public LinkedHashMap() { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public LinkedHashMap(@NonNegative int initialCapacity, + public @Modifiable LinkedHashMap(@NonNegative int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 88e006836ccc..2648dacd1c61 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -167,7 +167,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) -@AnnotatedFor({"lock", "nullness", "index"}) +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) public interface List extends Collection { // Query Operations diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index a4accc42e817..827fc5609f3a 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -28,6 +28,11 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -192,7 +197,7 @@ public interface Map { * @return the number of key-value mappings in this map */ @Pure - @NonNegative int size(@GuardSatisfied Map this); + @NonNegative int size(@UnknownModifiability @GuardSatisfied Map this); /** * Returns {@code true} if this map contains no key-value mappings. @@ -201,7 +206,7 @@ public interface Map { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied Map this); + boolean isEmpty(@UnknownModifiability @GuardSatisfied Map this); /** * Returns {@code true} if this map contains a mapping for the specified @@ -224,7 +229,7 @@ public interface Map { @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @EnsuresNonEmptyIf(result=true, expression={"this"}) @Pure - boolean containsKey(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); + boolean containsKey(@UnknownModifiability @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); /** * Returns {@code true} if this map maps one or more keys to the @@ -246,7 +251,7 @@ public interface Map { */ @EnsuresNonEmptyIf(result=true, expression={"this"}) @Pure - boolean containsValue(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); + boolean containsValue(@UnknownModifiability @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); /** * Returns the value to which the specified key is mapped, @@ -275,7 +280,7 @@ public interface Map { * (optional) */ @Pure - @Nullable V get(@GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); + @Nullable V get(@UnknownModifiability @GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); // Modification Operations @@ -306,7 +311,7 @@ public interface Map { @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) @EnsuresNonEmpty("this") - @Nullable V put(@GuardSatisfied Map this, K key, V value); + @Nullable V put(@Modifiable @GuardSatisfied Map this, K key, V value); /** * Removes the mapping for a key from this map if it is present @@ -339,7 +344,7 @@ public interface Map { * (optional) */ @CFComment("nullness: key is not @Nullable because this map might not permit null values") - @Nullable V remove(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); + @Nullable V remove(@Modifiable @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); // Bulk Operations @@ -363,7 +368,7 @@ public interface Map { * @throws IllegalArgumentException if some property of a key or value in * the specified map prevents it from being stored in this map */ - void putAll(@GuardSatisfied Map this, Map m); + void putAll(@Modifiable @GuardSatisfied Map this, Map m); /** * Removes all of the mappings from this map (optional operation). @@ -372,7 +377,7 @@ public interface Map { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this map */ - void clear(@GuardSatisfied Map this); + void clear(@Modifiable @GuardSatisfied Map this); // Views @@ -393,7 +398,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied @PolyNonEmpty Map this); + @PolyModifiable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -411,7 +416,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @PolyNonEmpty Collection values(@GuardSatisfied @PolyNonEmpty Map this); + @PolyModifiable @PolyNonEmpty Collection values(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -430,7 +435,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @PolyNonEmpty Set> entrySet(@GuardSatisfied @PolyNonEmpty Map this); + @PolyModifiable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the @@ -475,7 +480,7 @@ interface Entry { * removed from the backing map. */ @Pure - K getKey(Map.@GuardSatisfied Entry this); + K getKey(Map.@UnknownModifiability @GuardSatisfied Entry this); /** * Returns the value corresponding to this entry. If the mapping @@ -488,7 +493,7 @@ interface Entry { * removed from the backing map. */ @Pure - V getValue(Map.@GuardSatisfied Entry this); + V getValue(Map.@UnknownModifiability @GuardSatisfied Entry this); /** * Replaces the value corresponding to this entry with the specified @@ -510,7 +515,7 @@ interface Entry { * required to, throw this exception if the entry has been * removed from the backing map. */ - V setValue(Map.@GuardSatisfied Entry this, V value); + V setValue(Map.@Modifiable @GuardSatisfied Entry this, V value); /** * Compares the specified object with this entry for equality. @@ -531,7 +536,7 @@ interface Entry { * entry */ @Pure - boolean equals(Map.@GuardSatisfied Entry this, @GuardSatisfied @Nullable Object o); + boolean equals(Map.@UnknownModifiability @GuardSatisfied Entry this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this map entry. The hash code @@ -550,7 +555,7 @@ interface Entry { * @see #equals(Object) */ @Pure - int hashCode(Map.@GuardSatisfied Entry this); + int hashCode(Map.@UnknownModifiability @GuardSatisfied Entry this); /** * Returns a comparator that compares {@link Map.Entry} in natural order on key. @@ -650,7 +655,8 @@ public static Comparator> comparingByValue(Comparator Map.Entry copyOf(Map.Entry e) { + public static + Map.@Unmodifiable Entry copyOf(Map.@UnknownModifiability Entry e) { Objects.requireNonNull(e); if (e instanceof KeyValueHolder) { return (Map.Entry) e; @@ -674,7 +680,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @Nullable Object o); + boolean equals(@UnknownModifiability @GuardSatisfied Map this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this map. The hash code of a map is @@ -689,7 +695,7 @@ public static Comparator> comparingByValue(Comparator this); + int hashCode(@UnknownModifiability @GuardSatisfied Map this); // Defaultable methods @@ -803,7 +809,7 @@ default void forEach(@NonLeaked BiConsumer action) { * removed during iteration * @since 1.8 */ - default void replaceAll(BiFunction function) { + default void replaceAll(@Modifiable Map this, BiFunction function) { Objects.requireNonNull(function); for (Map.Entry entry : entrySet()) { K k; @@ -871,7 +877,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - default @Nullable V putIfAbsent(K key, V value) { + default @Nullable V putIfAbsent(@Modifiable Map this, K key, V value) { V v = get(key); if (v == null) { v = put(key, value); @@ -915,7 +921,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @CFComment("nullness: key and value are not @Nullable because this map might not permit null values") - default boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + default boolean remove(@Modifiable Map this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Object curValue = (key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { @@ -967,7 +973,7 @@ default boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSati * or value prevents it from being stored in this map * @since 1.8 */ - default boolean replace(K key, V oldValue, V newValue) { + default boolean replace(@Modifiable Map this, K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { @@ -1015,7 +1021,7 @@ default boolean replace(K key, V oldValue, V newValue) { * or value prevents it from being stored in this map * @since 1.8 */ - default @Nullable V replace(K key, V value) { + default @Nullable V replace(@Modifiable Map this, K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); @@ -1097,7 +1103,7 @@ default boolean replace(K key, V oldValue, V newValue) { * (optional) * @since 1.8 */ - default @PolyNull V computeIfAbsent(K key, + default @PolyNull V computeIfAbsent(@Modifiable Map this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V v; @@ -1174,7 +1180,7 @@ default boolean replace(K key, V oldValue, V newValue) { * (optional) * @since 1.8 */ - default @Nullable V computeIfPresent(K key, + default @Nullable V computeIfPresent(@Modifiable Map this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; @@ -1260,7 +1266,7 @@ default boolean replace(K key, V oldValue, V newValue) { * (optional) * @since 1.8 */ - default @Nullable V compute(K key, + default @Nullable V compute(@Modifiable Map this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue = get(key); @@ -1358,7 +1364,7 @@ default boolean replace(K key, V oldValue, V newValue) { * null * @since 1.8 */ - default @Nullable V merge(K key, @NonNull V value, + default @Nullable V merge(@Modifiable Map this, K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); @@ -1384,7 +1390,7 @@ default boolean replace(K key, V oldValue, V newValue) { * @since 9 */ @SuppressWarnings("unchecked") - static Map of() { + static @Unmodifiable Map of() { return (Map) ImmutableCollections.EMPTY_MAP; } @@ -1401,7 +1407,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1) { + static @Unmodifiable @NonEmpty Map of(K k1, V v1) { return new ImmutableCollections.Map1<>(k1, v1); } @@ -1421,7 +1427,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2) { + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2); } @@ -1443,7 +1449,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3) { + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3); } @@ -1467,7 +1473,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4); } @@ -1493,7 +1499,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } @@ -1521,7 +1527,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); @@ -1553,7 +1559,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); @@ -1587,7 +1593,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); @@ -1623,7 +1629,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); @@ -1661,7 +1667,7 @@ static Map of() { * * @since 9 */ - static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + static @Unmodifiable @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); @@ -1700,7 +1706,7 @@ static Map of() { */ @SafeVarargs @SuppressWarnings("varargs") - static @PolyNonEmpty Map ofEntries(Entry @PolyNonEmpty... entries) { + static @Unmodifiable @PolyNonEmpty Map ofEntries(Entry @PolyNonEmpty... entries) { if (entries.length == 0) { // implicit null check of entries array @SuppressWarnings("unchecked") var map = (Map) ImmutableCollections.EMPTY_MAP; @@ -1756,7 +1762,7 @@ static Map of() { * @see Map#ofEntries Map.ofEntries() * @since 9 */ - static Entry entry(@NonNull K k, @NonNull V v) { + static @Unmodifiable Entry entry(@NonNull K k, @NonNull V v) { // KeyValueHolder checks for nulls return new KeyValueHolder<>(k, v); } @@ -1779,7 +1785,7 @@ static Map of() { * @since 10 */ @SuppressWarnings({"rawtypes","unchecked"}) - static @PolyNonEmpty Map copyOf(@PolyNonEmpty Map map) { + static @Unmodifiable @PolyNonEmpty Map copyOf(@PolyNonEmpty Map map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map)map; } else { From aa363e9ac8d050f9e85e4840ee8aeb5efd2f49c0 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Dec 2025 00:44:55 -0800 Subject: [PATCH 003/119] annotated collection.java --- .../share/classes/java/util/Collection.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 8ea7ca4d9efa..06844ffa6b56 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -29,6 +29,11 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -280,7 +285,7 @@ public interface Collection extends Iterable { * @return the number of elements in this collection */ @Pure - @NonNegative int size(@GuardSatisfied Collection this); + @NonNegative int size(@UnknownModifiability @GuardSatisfied Collection this); /** * Returns {@code true} if this collection contains no elements. @@ -289,7 +294,7 @@ public interface Collection extends Iterable { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied Collection this); + boolean isEmpty(@UnknownModifiability @GuardSatisfied Collection this); /** * Returns {@code true} if this collection contains the specified element. @@ -312,7 +317,7 @@ public interface Collection extends Iterable { "(though I think a nicer specification would be to return false in that case)"}) @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@GuardSatisfied Collection this, @GuardSatisfied @UnknownSignedness Object o); + boolean contains(@UnknownModifiability @GuardSatisfied Collection this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns an iterator over the elements in this collection. There are no @@ -323,7 +328,7 @@ public interface Collection extends Iterable { * @return an {@code Iterator} over the elements in this collection */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Collection this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection this); /** * Returns an array containing all of the elements in this collection. @@ -352,7 +357,7 @@ public interface Collection extends Iterable { "methods, because the most useful type for toArray is not expressible", "in the surface syntax that the nullness annotations support."}) @SideEffectFree - @PolyNull @PolySigned Object[] toArray(Collection<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(@UnknownModifiability Collection<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this collection; @@ -406,7 +411,7 @@ public interface Collection extends Iterable { * @throws NullPointerException if the specified array is null */ @SideEffectFree - @Nullable T [] toArray(@PolyNull T[] a); + @Nullable T [] toArray(@UnknownModifiability Collection this, @PolyNull T[] a); /** * Returns an array containing all of the elements in this collection, @@ -443,7 +448,7 @@ public interface Collection extends Iterable { * @throws NullPointerException if the generator function is null * @since 11 */ - default T[] toArray(IntFunction generator) { + default T[] toArray(@UnknownModifiability Collection this, IntFunction generator) { return toArray(generator.apply(0)); } @@ -483,7 +488,7 @@ default T[] toArray(IntFunction generator) { * time due to insertion restrictions */ @EnsuresNonEmpty("this") - boolean add(@GuardSatisfied Collection this, E e); + boolean add(@Modifiable @GuardSatisfied Collection this, E e); /** * Removes a single instance of the specified element from this @@ -505,7 +510,7 @@ default T[] toArray(IntFunction generator) { * @throws UnsupportedOperationException if the {@code remove} operation * is not supported by this collection */ - boolean remove(@GuardSatisfied @Shrinkable Collection this, @UnknownSignedness Object o); + boolean remove(@Modifiable @GuardSatisfied @Shrinkable Collection this, @UnknownSignedness Object o); // Bulk Operations @@ -529,7 +534,7 @@ default T[] toArray(IntFunction generator) { * @see #contains(Object) */ @Pure - boolean containsAll(@GuardSatisfied Collection this, @GuardSatisfied Collection c); + boolean containsAll(@UnknownModifiability @GuardSatisfied Collection this, @GuardSatisfied Collection c); /** * Adds all of the elements in the specified collection to this collection @@ -555,7 +560,7 @@ default T[] toArray(IntFunction generator) { * this time due to insertion restrictions * @see #add(Object) */ - boolean addAll(@GuardSatisfied Collection this, Collection c); + boolean addAll(@Modifiable @GuardSatisfied Collection this, Collection c); /** * Removes all of this collection's elements that are also contained in the @@ -580,7 +585,7 @@ default T[] toArray(IntFunction generator) { * @see #remove(Object) * @see #contains(Object) */ - boolean removeAll(@GuardSatisfied @Shrinkable Collection this, Collection c); + boolean removeAll(@Modifiable @GuardSatisfied @Shrinkable Collection this, Collection c); /** * Removes all of the elements of this collection that satisfy the given @@ -604,7 +609,7 @@ default T[] toArray(IntFunction generator) { * supported. * @since 1.8 */ - default boolean removeIf(@Shrinkable Collection this, Predicate filter) { + default boolean removeIf(@Modifiable @Shrinkable Collection this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); @@ -639,7 +644,7 @@ default boolean removeIf(@Shrinkable Collection this, Predicate fi * @see #remove(Object) * @see #contains(Object) */ - boolean retainAll(@GuardSatisfied @Shrinkable Collection this, Collection c); + boolean retainAll(@Modifiable @GuardSatisfied @Shrinkable Collection this, Collection c); /** * Removes all of the elements from this collection (optional operation). @@ -648,7 +653,7 @@ default boolean removeIf(@Shrinkable Collection this, Predicate fi * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this collection */ - void clear(@GuardSatisfied @Shrinkable Collection this); + void clear(@Modifiable @GuardSatisfied @Shrinkable Collection this); // Comparison and hashing @@ -687,7 +692,7 @@ default boolean removeIf(@Shrinkable Collection this, Predicate fi * @see List#equals(Object) */ @Pure - boolean equals(@GuardSatisfied Collection this, @GuardSatisfied @Nullable @UnknownSignedness Object o); + boolean equals(@UnknownModifiability @GuardSatisfied Collection this, @GuardSatisfied @Nullable @UnknownSignedness Object o); /** * Returns the hash code value for this collection. While the @@ -705,7 +710,7 @@ default boolean removeIf(@Shrinkable Collection this, Predicate fi * @see Object#equals(Object) */ @Pure - int hashCode(@GuardSatisfied Collection this); + int hashCode(@UnknownModifiability @GuardSatisfied Collection this); /** * Creates a {@link Spliterator} over the elements in this collection. @@ -759,7 +764,7 @@ default boolean removeIf(@Shrinkable Collection this, Predicate fi */ @SideEffectFree @Override - default Spliterator spliterator() { + default Spliterator spliterator(@UnknownModifiability Collection this) { return Spliterators.spliterator(this, 0); } @@ -778,7 +783,7 @@ default Spliterator spliterator() { * @return a sequential {@code Stream} over the elements in this collection * @since 1.8 */ - default @PolyNonEmpty Stream stream(@PolyNonEmpty Collection this) { + default @PolyNonEmpty Stream stream(@UnknownModifiability @PolyNonEmpty Collection this) { return StreamSupport.stream(spliterator(), false); } @@ -799,7 +804,7 @@ default Spliterator spliterator() { * collection * @since 1.8 */ - default Stream parallelStream() { + default Stream parallelStream(@UnknownModifiability Collection this) { return StreamSupport.stream(spliterator(), true); } } From 1a38624c6d6aff900926ec62c187325cb7832612 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 3 Dec 2025 22:58:24 -0800 Subject: [PATCH 004/119] annotated set.java for modifiability --- .../share/classes/java/util/HashSet.java | 13 ++-- .../share/classes/java/util/Map.java | 4 +- .../share/classes/java/util/Set.java | 63 ++++++++++--------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 44120107618b..54fbde657abb 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -28,6 +28,9 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -119,7 +122,7 @@ public class HashSet * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public HashSet() { + public @Modifiable HashSet() { map = new HashMap<>(); } @@ -132,7 +135,7 @@ public HashSet() { * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } @@ -146,7 +149,7 @@ public HashSet() { * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -158,7 +161,7 @@ public HashSet(@NonNegative int initialCapacity, float loadFactor) { * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public HashSet(@NonNegative int initialCapacity) { + public @Modifiable HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -175,7 +178,7 @@ public HashSet(@NonNegative int initialCapacity) { * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 827fc5609f3a..bee994e57cdf 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -435,7 +435,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @PolyModifiable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @PolyModifiable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the @@ -1785,7 +1785,7 @@ default boolean replace(@Modifiable Map this, K key, V oldValue, V newValu * @since 10 */ @SuppressWarnings({"rawtypes","unchecked"}) - static @Unmodifiable @PolyNonEmpty Map copyOf(@PolyNonEmpty Map map) { + static @Unmodifiable @PolyNonEmpty Map copyOf(@UnknownModifiablity @PolyNonEmpty Map map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map)map; } else { diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 0db338eaaeb0..4b1614ab27d2 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -28,6 +28,11 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -141,7 +146,7 @@ public interface Set extends Collection { * @return the number of elements in this set (its cardinality) */ @Pure - @NonNegative int size(@GuardSatisfied Set this); + @NonNegative int size(@UnknownModifiability @GuardSatisfied Set this); /** * Returns {@code true} if this set contains no elements. @@ -150,7 +155,7 @@ public interface Set extends Collection { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied Set this); + boolean isEmpty(@UnknownModifiability @GuardSatisfied Set this); /** * Returns {@code true} if this set contains the specified element. @@ -169,7 +174,7 @@ public interface Set extends Collection { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@GuardSatisfied Set this, @GuardSatisfied @UnknownSignedness Object o); + boolean contains(@UnknownModifiability @GuardSatisfied Set this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns an iterator over the elements in this set. The elements are @@ -179,7 +184,7 @@ public interface Set extends Collection { * @return an iterator over the elements in this set */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Set this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Set this); /** * Returns an array containing all of the elements in this set. @@ -198,7 +203,7 @@ public interface Set extends Collection { * @return an array containing all the elements in this set */ @SideEffectFree - @PolyNull @PolySigned Object[] toArray(Set<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(@UnknownModifiability Set<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this set; the @@ -243,7 +248,7 @@ public interface Set extends Collection { * @throws NullPointerException if the specified array is null */ @SideEffectFree - @Nullable T [] toArray(@PolyNull T[] a); + @Nullable T [] toArray(@UnknownModifiability Set this, @PolyNull T[] a); // Modification Operations @@ -279,7 +284,7 @@ public interface Set extends Collection { * prevents it from being added to this set */ @EnsuresNonEmpty("this") - boolean add(@GuardSatisfied Set this, E e); + boolean add(@Modifiable @GuardSatisfied Set this, E e); /** @@ -303,7 +308,7 @@ public interface Set extends Collection { * @throws UnsupportedOperationException if the {@code remove} operation * is not supported by this set */ - boolean remove(@GuardSatisfied Set this, @UnknownSignedness Object o); + boolean remove(@Modifiable @GuardSatisfied Set this, @UnknownSignedness Object o); // Bulk Operations @@ -328,7 +333,7 @@ public interface Set extends Collection { * @see #contains(Object) */ @Pure - boolean containsAll(@GuardSatisfied Set this, @GuardSatisfied Collection c); + boolean containsAll(@UnknownModifiability @GuardSatisfied Set this, @GuardSatisfied Collection c); /** * Adds all of the elements in the specified collection to this set if @@ -353,7 +358,7 @@ public interface Set extends Collection { * @see #add(Object) */ @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@GuardSatisfied Set this, Collection c); + boolean addAll(@Modifiable @GuardSatisfied Set this, Collection c); /** * Retains only the elements in this set that are contained in the @@ -376,7 +381,7 @@ public interface Set extends Collection { * or if the specified collection is null * @see #remove(Object) */ - boolean retainAll(@GuardSatisfied Set this, Collection c); + boolean retainAll(@Modifiable @GuardSatisfied Set this, Collection c); /** * Removes from this set all of its elements that are contained in the @@ -399,7 +404,7 @@ public interface Set extends Collection { * @see #remove(Object) * @see #contains(Object) */ - boolean removeAll(@GuardSatisfied Set this, Collection c); + boolean removeAll(@Modifiable @GuardSatisfied Set this, Collection c); /** * Removes all of the elements from this set (optional operation). @@ -408,7 +413,7 @@ public interface Set extends Collection { * @throws UnsupportedOperationException if the {@code clear} method * is not supported by this set */ - void clear(@GuardSatisfied Set this); + void clear(@Modifiable @GuardSatisfied Set this); // Comparison and hashing @@ -426,7 +431,7 @@ public interface Set extends Collection { * @return {@code true} if the specified object is equal to this set */ @Pure - boolean equals(@GuardSatisfied Set this, @GuardSatisfied @Nullable Object o); + boolean equals(@UnknownModifiability @GuardSatisfied Set this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this set. The hash code of a set is @@ -442,7 +447,7 @@ public interface Set extends Collection { * @see Set#equals(Object) */ @Pure - int hashCode(@GuardSatisfied Set this); + int hashCode(@UnknownModifiability @GuardSatisfied Set this); /** * Creates a {@code Spliterator} over the elements in this set. @@ -468,7 +473,7 @@ public interface Set extends Collection { * @since 1.8 */ @Override - default Spliterator spliterator() { + default Spliterator spliterator(@UnknownModifiability Set this) { return Spliterators.spliterator(this, Spliterator.DISTINCT); } @@ -482,7 +487,7 @@ default Spliterator spliterator() { * @since 9 */ @SuppressWarnings("unchecked") - static Set of() { + static @Unmodifiable Set of() { return (Set) ImmutableCollections.EMPTY_SET; } @@ -497,7 +502,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1) { + static @Unmodifiable @NonEmpty Set of(E e1) { return new ImmutableCollections.Set12<>(e1); } @@ -514,7 +519,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2) { return new ImmutableCollections.Set12<>(e1, e2); } @@ -532,7 +537,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3) { return new ImmutableCollections.SetN<>(e1, e2, e3); } @@ -551,7 +556,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4); } @@ -571,7 +576,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5); } @@ -592,7 +597,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6); } @@ -615,7 +620,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7); } @@ -639,7 +644,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7, e8); } @@ -664,7 +669,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7, e8, e9); } @@ -690,7 +695,7 @@ static Set of() { * * @since 9 */ - static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { + static @Unmodifiable @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } @@ -723,7 +728,7 @@ static Set of() { */ @SafeVarargs @SuppressWarnings("varargs") - static Set of(E... elements) { + static @Unmodifiable Set of(E... elements) { switch (elements.length) { // implicit null check of elements case 0: @SuppressWarnings("unchecked") @@ -756,7 +761,7 @@ static Set of(E... elements) { * @since 10 */ @SuppressWarnings("unchecked") - static @PolyNonEmpty Set copyOf(@PolyNonEmpty Collection coll) { + static @Unmodifiable @PolyNonEmpty Set copyOf(@UnknownModifiability @PolyNonEmpty Collection coll) { if (coll instanceof ImmutableCollections.AbstractImmutableSet) { return (Set)coll; } else { From 575780fef3d0027c833da03cf82803132321d78d Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 7 Dec 2025 02:36:12 -0800 Subject: [PATCH 005/119] finished annotations in Collections.java on modifiability --- .../share/classes/java/util/Collections.java | 153 +++++++++--------- .../share/classes/java/util/Enumeration.java | 3 +- .../share/classes/java/util/Iterator.java | 3 +- .../share/classes/java/util/LinkedList.java | 5 +- .../share/classes/java/util/TreeMap.java | 9 +- .../share/classes/java/util/TreeSet.java | 9 +- 6 files changed, 96 insertions(+), 86 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 67a03e21d3b8..cab2e317a64f 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -29,6 +29,11 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -166,7 +171,7 @@ private Collections() { * @see List#sort(Comparator) */ @SuppressWarnings("unchecked") - public static > void sort(List list) { + public static > void sort(@Modifiable List list) { list.sort(null); } @@ -200,7 +205,7 @@ public static > void sort(List list) { * @see List#sort(Comparator) */ @SuppressWarnings({"unchecked", "rawtypes"}) - public static void sort(List list, @Nullable Comparator c) { + public static void sort(@Modifiable List list, @Nullable Comparator c) { list.sort(c); } @@ -237,7 +242,7 @@ public static void sort(List list, @Nullable Comparator c) { * with the elements of the list. */ public static - int binarySearch(List> list, T key) { + int binarySearch(@UnknownModifiability List> list, T key) { if (list instanceof RandomAccess || list.size()> list, T key) { } private static - int indexedBinarySearch(List> list, T key) { + int indexedBinarySearch(@UnknownModifiability List> list, T key) { int low = 0; int high = list.size()-1; @@ -265,7 +270,7 @@ else if (cmp > 0) } private static - int iteratorBinarySearch(List> list, T key) + int iteratorBinarySearch(@UnknownModifiability List> list, T key) { int low = 0; int high = list.size()-1; @@ -341,7 +346,7 @@ private static T get(ListIterator i, int index) { * elements of the list using this comparator. */ @SuppressWarnings("unchecked") - public static int binarySearch(List list, T key, @Nullable Comparator c) { + public static int binarySearch(@UnknownModifiability List list, T key, @Nullable Comparator c) { if (c==null) return binarySearch((List>) list, key); @@ -351,7 +356,7 @@ public static int binarySearch(List list, T key, @Nullable Comp return Collections.iteratorBinarySearch(list, key, c); } - private static int indexedBinarySearch(List l, T key, Comparator c) { + private static int indexedBinarySearch(@UnknownModifiability List l, T key, Comparator c) { int low = 0; int high = l.size()-1; @@ -370,7 +375,7 @@ else if (cmp > 0) return -(low + 1); // key not found } - private static int iteratorBinarySearch(List l, T key, Comparator c) { + private static int iteratorBinarySearch(@UnknownModifiability List l, T key, Comparator c) { int low = 0; int high = l.size()-1; ListIterator i = l.listIterator(); @@ -400,7 +405,7 @@ else if (cmp > 0) * its list-iterator does not support the {@code set} operation. */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void reverse(@GuardSatisfied List list) { + public static void reverse(@Modifiable @GuardSatisfied List list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i list) { * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the {@code set} operation. */ - public static void shuffle(@GuardSatisfied List list) { + public static void shuffle(@Modifiable @GuardSatisfied List list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); // harmless race. @@ -480,7 +485,7 @@ public static void shuffle(@GuardSatisfied List list) { * list-iterator does not support the {@code set} operation. */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void shuffle(@GuardSatisfied List list, Random rnd) { + public static void shuffle(@Modifiable @GuardSatisfied List list, Random rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) @@ -518,7 +523,7 @@ public static void shuffle(@GuardSatisfied List list, Random rnd) { * @since 1.4 */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void swap(@GuardSatisfied List list, int i, int j) { + public static void swap(@Modifiable @GuardSatisfied List list, int i, int j) { // instead of using a raw type here, it's possible to capture // the wildcard but it will require a call to a supplementary // private method @@ -547,7 +552,7 @@ private static void swap(Object[] arr, int i, int j) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void fill(@GuardSatisfied List list, T obj) { + public static void fill(@Modifiable @GuardSatisfied List list, T obj) { int size = list.size(); if (size < FILL_THRESHOLD || list instanceof RandomAccess) { @@ -580,7 +585,7 @@ public static void fill(@GuardSatisfied List list, T obj) { * @throws UnsupportedOperationException if the destination list's * list-iterator does not support the {@code set} operation. */ - public static void copy(List dest, List src) { + public static void copy(@Modifiable List dest, @UnknownModifiability List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -623,7 +628,7 @@ public static void copy(List dest, List src) { */ @Pure @StaticallyExecutable - public static > T min(Collection coll) { + public static > T min(@UnknownModifiability Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); @@ -661,7 +666,7 @@ public static > T min(Collection T min(Collection coll, @Nullable Comparator comp) { + public static T min(@UnknownModifiability Collection coll, @Nullable Comparator comp) { if (comp==null) return (T)min((Collection) coll); @@ -700,7 +705,7 @@ public static T min(Collection coll, @Nullable Comparator> T max(Collection coll) { + public static > T max(@UnknownModifiability Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); @@ -738,7 +743,7 @@ public static > T max(Collection T max(Collection coll, @Nullable Comparator comp) { + public static T max(@UnknownModifiability Collection coll, @Nullable Comparator comp) { if (comp==null) return (T)max((Collection) coll); @@ -808,7 +813,7 @@ public static T max(Collection coll, @Nullable Comparator list, int distance) { + public static void rotate(@Modifiable @GuardSatisfied List list, int distance) { if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) rotate1(list, distance); else @@ -872,7 +877,7 @@ private static void rotate2(List list, int distance) { * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static boolean replaceAll(List list, @Nullable T oldVal, T newVal) { + public static boolean replaceAll(@Modifiable List list, @Nullable T oldVal, T newVal) { boolean result = false; int size = list.size(); if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { @@ -933,7 +938,7 @@ public static boolean replaceAll(List list, @Nullable T oldVal, T newVal) * @since 1.4 */ @Pure - public static @GTENegativeOne int indexOfSubList(@GuardSatisfied List source, @GuardSatisfied List target) { + public static @GTENegativeOne int indexOfSubList(@UnknownModifiability @GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; @@ -987,7 +992,7 @@ public static boolean replaceAll(List list, @Nullable T oldVal, T newVal) * @since 1.4 */ @Pure - public static @GTENegativeOne int lastIndexOfSubList(@GuardSatisfied List source, @GuardSatisfied List target) { + public static @GTENegativeOne int lastIndexOfSubList(@UnknownModifiability @GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; @@ -1051,7 +1056,7 @@ public static boolean replaceAll(List list, @Nullable T oldVal, T newVal) */ @SuppressWarnings("unchecked") @SideEffectFree - public static @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@PolyGrowShrink @PolyNonEmpty Collection c) { + public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Collection c) { if (c.getClass() == UnmodifiableCollection.class) { return (Collection) c; } @@ -1178,7 +1183,7 @@ public Stream parallelStream() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @PolyNonEmpty Set unmodifiableSet(@PolyNonEmpty Set s) { + public static @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@UnknownModifiability @PolyNonEmpty Set s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSet.class) { return (Set) s; @@ -1216,7 +1221,7 @@ static class UnmodifiableSet extends UnmodifiableCollection * returned. * @return an unmodifiable view of the specified sorted set. */ - public static @PolyNonEmpty SortedSet unmodifiableSortedSet(@PolyNonEmpty SortedSet s) { + public static @Unmodifiable @PolyNonEmpty SortedSet unmodifiableSortedSet(@UnknownModifiability @PolyNonEmpty SortedSet s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSortedSet.class) { return s; @@ -1271,7 +1276,7 @@ public SortedSet tailSet(E fromElement) { * @return an unmodifiable view of the specified navigable set * @since 1.8 */ - public static @PolyNonEmpty NavigableSet unmodifiableNavigableSet(@PolyNonEmpty NavigableSet s) { + public static @Unmodifiable @PolyNonEmpty NavigableSet unmodifiableNavigableSet(@UnknownModifiability @PolyNonEmpty NavigableSet s) { if (s.getClass() == UnmodifiableNavigableSet.class) { return s; } @@ -1367,7 +1372,7 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @return an unmodifiable view of the specified list. */ @SuppressWarnings("unchecked") - public static @PolyGrowShrink @PolyNonEmpty List unmodifiableList(@PolyGrowShrink @PolyNonEmpty List list) { + public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty List unmodifiableList(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty List list) { if (list.getClass() == UnmodifiableList.class || list.getClass() == UnmodifiableRandomAccessList.class) { return (List) list; } @@ -1528,7 +1533,7 @@ private Object writeReplace() { * @return an unmodifiable view of the specified map. */ @SuppressWarnings("unchecked") - public static @PolyNonEmpty Map unmodifiableMap(@PolyNonEmpty Map m) { + public static @Unmodifiable @PolyNonEmpty Map unmodifiableMap(@UnknownModifiability @PolyNonEmpty Map m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableMap.class) { return (Map) m; @@ -1902,7 +1907,7 @@ && eq(e.getKey(), t.getKey()) * @return an unmodifiable view of the specified sorted map. */ @SuppressWarnings("unchecked") - public static @PolyNonEmpty SortedMap unmodifiableSortedMap(@PolyNonEmpty SortedMap m) { + public static @Unmodifiable @PolyNonEmpty SortedMap unmodifiableSortedMap(@UnknownModifiability @PolyNonEmpty SortedMap m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableSortedMap.class) { return (SortedMap) m; @@ -1957,7 +1962,7 @@ public SortedMap tailMap(K fromKey) * @since 1.8 */ @SuppressWarnings("unchecked") - public static @PolyNonEmpty NavigableMap unmodifiableNavigableMap(@PolyNonEmpty NavigableMap m) { + public static @Unmodifiable @PolyNonEmpty NavigableMap unmodifiableNavigableMap(@UnknownModifiability @PolyNonEmpty NavigableMap m) { if (m.getClass() == UnmodifiableNavigableMap.class) { return (NavigableMap) m; } @@ -2129,11 +2134,11 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) * @param c the collection to be "wrapped" in a synchronized collection. * @return a synchronized view of the specified collection. */ - public static @PolyGrowShrink @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyNonEmpty Collection c) { + public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection synchronizedCollection(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { return new SynchronizedCollection<>(c); } - static @PolyGrowShrink @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyNonEmpty Collection c, Object mutex) { + static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection synchronizedCollection(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection c, Object mutex) { return new SynchronizedCollection<>(c, mutex); } @@ -2272,11 +2277,11 @@ private void writeObject(ObjectOutputStream s) throws IOException { * @param s the set to be "wrapped" in a synchronized set. * @return a synchronized view of the specified set. */ - public static Set synchronizedSet(Set s) { + public static @PolyModifiable Set synchronizedSet(@PolyModifiable Set s) { return new SynchronizedSet<>(s); } - static Set synchronizedSet(Set s, Object mutex) { + static @PolyModifiable Set synchronizedSet(@PolyModifiable Set s, Object mutex) { return new SynchronizedSet<>(s, mutex); } @@ -2345,7 +2350,7 @@ public int hashCode() { * @param s the sorted set to be "wrapped" in a synchronized sorted set. * @return a synchronized view of the specified sorted set. */ - public static SortedSet synchronizedSortedSet(SortedSet s) { + public static @PolyModifiable SortedSet synchronizedSortedSet(@PolyModifiable SortedSet s) { return new SynchronizedSortedSet<>(s); } @@ -2441,7 +2446,7 @@ public E last() { * @return a synchronized view of the specified navigable set * @since 1.8 */ - public static NavigableSet synchronizedNavigableSet(NavigableSet s) { + public static @PolyModifiable NavigableSet synchronizedNavigableSet(@PolyModifiable NavigableSet s) { return new SynchronizedNavigableSet<>(s); } @@ -2545,13 +2550,13 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @param list the list to be "wrapped" in a synchronized list. * @return a synchronized view of the specified list. */ - public static @PolyGrowShrink @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyNonEmpty List list) { + public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty List synchronizedList(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list) : new SynchronizedList<>(list)); } - static @PolyGrowShrink @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyNonEmpty List list, Object mutex) { + static @PolyModifiable @PolyGrowShrink @PolyNonEmpty List synchronizedList(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List list, Object mutex) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list, mutex) : new SynchronizedList<>(list, mutex)); @@ -2722,7 +2727,7 @@ private Object writeReplace() { * @param m the map to be "wrapped" in a synchronized map. * @return a synchronized view of the specified map. */ - public static Map synchronizedMap(Map m) { + public static @PolyModifiable Map synchronizedMap(@PolyModifiable Map m) { return new SynchronizedMap<>(m); } @@ -2929,7 +2934,7 @@ private void writeObject(ObjectOutputStream s) throws IOException { * @param m the sorted map to be "wrapped" in a synchronized sorted map. * @return a synchronized view of the specified sorted map. */ - public static SortedMap synchronizedSortedMap(SortedMap m) { + public static @PolyModifiable SortedMap synchronizedSortedMap(@PolyModifiable SortedMap m) { return new SynchronizedSortedMap<>(m); } @@ -3034,7 +3039,7 @@ public K lastKey() { * @return a synchronized view of the specified navigable map. * @since 1.8 */ - public static NavigableMap synchronizedNavigableMap(NavigableMap m) { + public static @PolyModifiable NavigableMap synchronizedNavigableMap(@PolyModifiable NavigableMap m) { return new SynchronizedNavigableMap<>(m); } @@ -3222,7 +3227,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { * @return a dynamically typesafe view of the specified collection * @since 1.5 */ - public static @PolyGrowShrink @PolyNonEmpty Collection checkedCollection(@PolyGrowShrink @PolyNonEmpty Collection c, + public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection checkedCollection(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection c, Class type) { return new CheckedCollection<>(c, type); } @@ -3392,7 +3397,7 @@ public boolean removeIf(Predicate filter) { * @return a dynamically typesafe view of the specified queue * @since 1.8 */ - public static @PolyGrowShrink @PolyNonEmpty Queue checkedQueue(@PolyGrowShrink @PolyNonEmpty Queue queue, Class type) { + public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Queue checkedQueue(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Queue queue, Class type) { return new CheckedQueue<>(queue, type); } @@ -3452,7 +3457,7 @@ static class CheckedQueue * @return a dynamically typesafe view of the specified set * @since 1.5 */ - public static Set checkedSet(Set s, Class type) { + public static @PolyModifiable Set checkedSet(@PolyModifiable Set s, Class type) { return new CheckedSet<>(s, type); } @@ -3499,7 +3504,7 @@ static class CheckedSet extends CheckedCollection * @return a dynamically typesafe view of the specified sorted set * @since 1.5 */ - public static SortedSet checkedSortedSet(SortedSet s, + public static @PolyModifiable SortedSet checkedSortedSet(@PolyModifiable SortedSet s, Class type) { return new CheckedSortedSet<>(s, type); } @@ -3564,7 +3569,7 @@ public SortedSet tailSet(E fromElement) { * @return a dynamically typesafe view of the specified navigable set * @since 1.8 */ - public static NavigableSet checkedNavigableSet(NavigableSet s, + public static @PolyModifiable NavigableSet checkedNavigableSet(@PolyModifiable NavigableSet s, Class type) { return new CheckedNavigableSet<>(s, type); } @@ -3647,7 +3652,7 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @return a dynamically typesafe view of the specified list * @since 1.5 */ - public static @PolyGrowShrink @PolyNonEmpty List checkedList(@PolyGrowShrink @PolyNonEmpty List list, Class type) { + public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty List checkedList(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List list, Class type) { return (list instanceof RandomAccess ? new CheckedRandomAccessList<>(list, type) : new CheckedList<>(list, type)); @@ -3799,7 +3804,7 @@ public List subList(int fromIndex, int toIndex) { * @return a dynamically typesafe view of the specified map * @since 1.5 */ - public static Map checkedMap(Map m, + public static @PolyModifiable Map checkedMap(@PolyModifiable Map m, Class keyType, Class valueType) { return new CheckedMap<>(m, keyType, valueType); @@ -4217,7 +4222,7 @@ public boolean equals(Object o) { * @return a dynamically typesafe view of the specified map * @since 1.5 */ - public static SortedMap checkedSortedMap(SortedMap m, + public static @PolyModifiable SortedMap checkedSortedMap(@PolyModifiable SortedMap m, Class keyType, Class valueType) { return new CheckedSortedMap<>(m, keyType, valueType); @@ -4296,7 +4301,7 @@ public SortedMap tailMap(K fromKey) { * @return a dynamically typesafe view of the specified map * @since 1.8 */ - public static NavigableMap checkedNavigableMap(NavigableMap m, + public static @PolyModifiable NavigableMap checkedNavigableMap(@PolyModifiable NavigableMap m, Class keyType, Class valueType) { return new CheckedNavigableMap<>(m, keyType, valueType); @@ -4465,7 +4470,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { */ @SuppressWarnings("unchecked") @SideEffectFree - public static Iterator emptyIterator() { + public static @Unmodifiable Iterator emptyIterator() { return (Iterator) EmptyIterator.EMPTY_ITERATOR; } @@ -4513,7 +4518,7 @@ public void forEachRemaining(Consumer action) { */ @SuppressWarnings("unchecked") @SideEffectFree - public static ListIterator emptyListIterator() { + public static @Unmodifiable ListIterator emptyListIterator() { return (ListIterator) EmptyListIterator.EMPTY_ITERATOR; } @@ -4571,7 +4576,7 @@ private static class EmptyEnumeration implements Enumeration { * @see #emptySet() */ @SuppressWarnings("rawtypes") - public static final Set EMPTY_SET = new EmptySet<>(); + public static final @Unmodifiable Set EMPTY_SET = new EmptySet<>(); /** * Returns an empty set (immutable). This set is serializable. @@ -4594,7 +4599,7 @@ private static class EmptyEnumeration implements Enumeration { */ @SuppressWarnings("unchecked") @SideEffectFree - public static final Set emptySet() { + public static final @Unmodifiable Set emptySet() { return (Set) EMPTY_SET; } @@ -4678,7 +4683,7 @@ public int hashCode() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static SortedSet emptySortedSet() { + public static @Unmodifiable SortedSet emptySortedSet() { return (SortedSet) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET; } @@ -4700,7 +4705,7 @@ public static SortedSet emptySortedSet() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static NavigableSet emptyNavigableSet() { + public static @Unmodifiable NavigableSet emptyNavigableSet() { return (NavigableSet) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET; } @@ -4710,7 +4715,7 @@ public static NavigableSet emptyNavigableSet() { * @see #emptyList() */ @SuppressWarnings("rawtypes") - public static final List EMPTY_LIST = new EmptyList<>(); + public static final @Unmodifiable List EMPTY_LIST = new EmptyList<>(); /** * Returns an empty list (immutable). This list is serializable. @@ -4734,7 +4739,7 @@ public static NavigableSet emptyNavigableSet() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static final List emptyList() { + public static final @Unmodifiable List emptyList() { return (List) EMPTY_LIST; } @@ -4825,7 +4830,7 @@ private Object readResolve() { * @since 1.3 */ @SuppressWarnings("rawtypes") - public static final Map EMPTY_MAP = new EmptyMap<>(); + public static final @Unmodifiable Map EMPTY_MAP = new EmptyMap<>(); /** * Returns an empty map (immutable). This map is serializable. @@ -4847,7 +4852,7 @@ private Object readResolve() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static final Map emptyMap() { + public static final @Unmodifiable Map emptyMap() { return (Map) EMPTY_MAP; } @@ -4869,7 +4874,7 @@ public static final Map emptyMap() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static final SortedMap emptySortedMap() { + public static final @Unmodifiable SortedMap emptySortedMap() { return (SortedMap) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP; } @@ -4891,7 +4896,7 @@ public static final SortedMap emptySortedMap() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static final NavigableMap emptyNavigableMap() { + public static final @Unmodifiable NavigableMap emptyNavigableMap() { return (NavigableMap) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP; } @@ -5008,11 +5013,11 @@ private Object readResolve() { * @param o the sole object to be stored in the returned set. * @return an immutable set containing only the specified object. */ - public static Set singleton(T o) { + public static @Unmodifiable Set singleton(T o) { return new SingletonSet<>(o); } - static Iterator singletonIterator(final E e) { + static @Unmodifiable Iterator singletonIterator(final E e) { return new Iterator() { private boolean hasNext = true; @Pure @@ -5048,7 +5053,7 @@ public void forEachRemaining(Consumer action) { * @param Type of elements * @return A singleton {@code Spliterator} */ - static Spliterator singletonSpliterator(final T element) { + static Spliterator singletonSpliterator(final T element) { return new Spliterator() { long est = 1; @@ -5144,7 +5149,7 @@ public int hashCode() { * @return an immutable list containing only the specified object. * @since 1.3 */ - public static @ArrayLen(1) List singletonList(T o) { + public static @Unmodifiable @ArrayLen(1) List singletonList(T o) { return new SingletonList<>(o); } @@ -5222,7 +5227,7 @@ public int hashCode() { * mapping. * @since 1.3 */ - public static Map singletonMap(K key, V value) { + public static @Unmodifiable Map singletonMap(K key, V value) { return new SingletonMap<>(key, value); } @@ -5368,7 +5373,7 @@ public int hashCode() { * @see List#addAll(Collection) * @see List#addAll(int, Collection) */ - public static List nCopies(@NonNegative int n, T o) { + public static @Unmodifiable List nCopies(@NonNegative int n, T o) { if (n < 0) throw new IllegalArgumentException("List length = " + n); return new CopiesList<>(n, o); @@ -5698,7 +5703,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) { * @see Enumeration * @see ArrayList */ - public static ArrayList list(Enumeration e) { + public static @Modifiable ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); @@ -5727,7 +5732,7 @@ static boolean eq(Object o1, Object o2) { * @throws NullPointerException if {@code c} is null * @since 1.5 */ - public static @NonNegative int frequency(Collection c, @Nullable Object o) { + public static @NonNegative int frequency(@UnknownModifiability Collection c, @Nullable Object o) { int result = 0; if (o == null) { for (Object e : c) @@ -5779,7 +5784,7 @@ static boolean eq(Object o1, Object o2) { * (optional) * @since 1.5 */ - public static boolean disjoint(Collection c1, Collection c2) { + public static boolean disjoint(@UnknownModifiability Collection c1, @UnknownModifiability Collection c2) { // The collection to be used for contains(). Preference is given to // the collection who's contains() has lower O() complexity. Collection contains = c2; @@ -5858,7 +5863,7 @@ public static boolean disjoint(Collection c1, Collection c2) { * @since 1.5 */ @SafeVarargs - public static boolean addAll(@GuardSatisfied Collection c, T... elements) { + public static boolean addAll(@Modifiable @GuardSatisfied Collection c, T... elements) { boolean result = false; for (T element : elements) result |= c.add(element); @@ -5897,7 +5902,7 @@ public static boolean addAll(@GuardSatisfied Collection c, T... e * @since 1.6 */ @SideEffectFree - public static Set newSetFromMap(Map map) { + public static @PolyModifiable Set newSetFromMap(@PolyModifiable Map map) { return new SetFromMap<>(map); } @@ -5993,7 +5998,7 @@ private void readObject(java.io.ObjectInputStream stream) * @return the queue * @since 1.6 */ - public static @PolyGrowShrink @PolyNonEmpty Queue asLifoQueue(@PolyGrowShrink @PolyNonEmpty Deque deque) { + public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Queue asLifoQueue(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Deque deque) { return new AsLIFOQueue<>(Objects.requireNonNull(deque)); } diff --git a/src/java.base/share/classes/java/util/Enumeration.java b/src/java.base/share/classes/java/util/Enumeration.java index 27b026817077..480b650452cb 100644 --- a/src/java.base/share/classes/java/util/Enumeration.java +++ b/src/java.base/share/classes/java/util/Enumeration.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -124,7 +125,7 @@ public interface Enumeration { * * @since 9 */ - default Iterator asIterator() { + default @Unmodifiable Iterator asIterator() { return new Iterator<>() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index fb353dbdc2ef..631c4032ed9c 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -116,7 +117,7 @@ public interface Iterator { * been called after the last call to the {@code next} * method */ - default void remove(@GuardSatisfied @Shrinkable Iterator this) { + default void remove(@Modifiable @GuardSatisfied @Shrinkable Iterator this) { throw new UnsupportedOperationException("remove"); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index 1cea55d756b7..7e5d2caa8859 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -129,7 +130,7 @@ void dataStructureInvariants() { /** * Constructs an empty list. */ - public LinkedList() { + public @Modifiable LinkedList() { } /** @@ -140,7 +141,7 @@ public LinkedList() { * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ - public @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { this(); addAll(c); } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index b9cd216b7141..68d85776cf04 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -165,7 +166,7 @@ public class TreeMap * {@code put(Object key, Object value)} call will throw a * {@code ClassCastException}. */ - public TreeMap() { + public @Modifiable TreeMap() { comparator = null; } @@ -183,7 +184,7 @@ public TreeMap() { * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ - public TreeMap(@Nullable Comparator comparator) { + public @Modifiable TreeMap(@Nullable Comparator comparator) { this.comparator = comparator; } @@ -201,7 +202,7 @@ public TreeMap(@Nullable Comparator comparator) { * or are not mutually comparable * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { + public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { comparator = null; putAll(m); } @@ -215,7 +216,7 @@ public TreeMap(@Nullable Comparator comparator) { * and whose comparator is to be used to sort this map * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { + public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index ce8e1c663d13..f0af706bc6eb 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -137,7 +138,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public TreeSet() { + public @Modifiable TreeSet() { this(new TreeMap<>()); } @@ -154,7 +155,7 @@ public TreeSet() { * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public TreeSet(@Nullable Comparator comparator) { + public @Modifiable TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -172,7 +173,7 @@ public TreeSet(@Nullable Comparator comparator) { * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -184,7 +185,7 @@ public TreeSet(@Nullable Comparator comparator) { * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } From c0c3c7686f87d4f380c72d0699dde462a719c5fb Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sat, 3 Jan 2026 16:15:04 -0800 Subject: [PATCH 006/119] annotated itentityHashMap and LinkedHashSet as modifiable. --- .../share/classes/java/util/IdentityHashMap.java | 5 +++-- .../share/classes/java/util/LinkedHashSet.java | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 8239894e498f..3808770dc366 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; @@ -227,7 +228,7 @@ static final Object unmaskNull(Object key) { * Constructs a new, empty identity hash map with a default expected * maximum size (21). */ - public IdentityHashMap() { + public @Modifiable IdentityHashMap() { init(DEFAULT_CAPACITY); } @@ -240,7 +241,7 @@ public IdentityHashMap() { * @param expectedMaxSize the expected maximum size of the map * @throws IllegalArgumentException if {@code expectedMaxSize} is negative */ - public IdentityHashMap(@NonNegative int expectedMaxSize) { + public @Modifiable IdentityHashMap(@NonNegative int expectedMaxSize) { if (expectedMaxSize < 0) throw new IllegalArgumentException("expectedMaxSize is negative: " + expectedMaxSize); diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 5886265bd039..a74614095a55 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -25,6 +25,10 @@ package java.util; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; + import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -136,7 +140,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public LinkedHashSet(int initialCapacity, float loadFactor) { + public @Modifiable LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } @@ -148,7 +152,7 @@ public LinkedHashSet(int initialCapacity, float loadFactor) { * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public LinkedHashSet(int initialCapacity) { + public @Modifiable LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } @@ -156,7 +160,7 @@ public LinkedHashSet(int initialCapacity) { * Constructs a new, empty linked hash set with the default initial * capacity (16) and load factor (0.75). */ - public LinkedHashSet() { + public @Modifiable LinkedHashSet() { super(16, .75f, true); } @@ -170,7 +174,7 @@ public LinkedHashSet() { * this set * @throws NullPointerException if the specified collection is null */ - public LinkedHashSet(Collection c) { + public @Modifiable LinkedHashSet(Collection c) { super(Math.max(2*c.size(), 11), .75f, true); addAll(c); } From fa7c2f310a7ef94c7939a4dbe9d2b3e04fc45a26 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 18 Jan 2026 20:07:11 -0800 Subject: [PATCH 007/119] annotated modifiable classes --- src/java.base/share/classes/java/util/ArrayList.java | 2 +- .../share/classes/java/util/Collections.java | 4 ++-- src/java.base/share/classes/java/util/HashMap.java | 2 +- src/java.base/share/classes/java/util/HashSet.java | 2 +- src/java.base/share/classes/java/util/Iterator.java | 2 +- .../share/classes/java/util/LinkedHashMap.java | 2 +- .../share/classes/java/util/LinkedHashSet.java | 2 +- src/java.base/share/classes/java/util/LinkedList.java | 2 +- src/java.base/share/classes/java/util/TreeMap.java | 2 +- src/java.base/share/classes/java/util/TreeSet.java | 4 ++-- src/java.base/share/classes/java/util/Vector.java | 11 ++++++----- 11 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 62e8c3c62ef3..42153d447e52 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -133,7 +133,7 @@ */ @CFComment("lock/nullness: Permit null elements") @AnnotatedFor({"lock", "nullness", "index"}) -public class ArrayList extends AbstractList +public @Modifiable class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @java.io.Serial diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 2f203b056de3..ba4e7e8c89e3 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -482,7 +482,7 @@ public static void shuffle(@Modifiable @GuardSatisfied List list) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void shuffle(List list, Random rnd) { + public static void shuffle(@Modifiable List list, Random rnd) { shuffle(list, (RandomGenerator) rnd); } @@ -4693,7 +4693,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @Unmodifiable Iterator emptyIterator() { + public static @Modifiable Iterator emptyIterator() { return (Iterator) EmptyIterator.EMPTY_ITERATOR; } diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 90cee63cec86..02cff3d42106 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -158,7 +158,7 @@ * @since 1.2 */ @AnnotatedFor({"lock", "nullness", "index"}) -public class HashMap extends AbstractMap +public @Modifiable class HashMap extends AbstractMap implements Map, Cloneable, Serializable { @java.io.Serial diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 8732b6a35245..90f1c0ac9a4f 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -106,7 +106,7 @@ */ @AnnotatedFor({"lock", "nullness", "index"}) -public class HashSet +public @Modifiable class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index 631c4032ed9c..46115fdc8f10 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -69,7 +69,7 @@ @CFComment({"nullness: This @Covariant annotation is sound, but it would not be sound on", "ListIterator (a subclass of Iterator), which supports a set operation." }) -@AnnotatedFor({"lock", "nullness"}) +@AnnotatedFor({"lock", "nullness", "modifiability"}) @Covariant({0}) public interface Iterator { /** diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 76f0d81fb789..4029c71fe3f9 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -189,7 +189,7 @@ * @since 1.4 */ @AnnotatedFor({"lock", "nullness", "index"}) -public class LinkedHashMap +public @Modifiable class LinkedHashMap extends HashMap implements SequencedMap { diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 2e93a858159f..922ea62a85e2 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -128,7 +128,7 @@ @CFComment({"lock/nullness: This class permits null elements"}) @AnnotatedFor({"lock", "nullness"}) -public class LinkedHashSet +public @Modifiable class LinkedHashSet extends HashSet implements SequencedSet, Cloneable, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index da6f0408a805..177032c4fd41 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -110,7 +110,7 @@ @CFComment({"lock/nullness: This class permits null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) -public class LinkedList +public @Modifiable class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 2e477c846c49..4064a2092613 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -140,7 +140,7 @@ @CFComment({"lock/nullness: This permits null element when using a custom comparator that allows null"}) @AnnotatedFor({"lock", "nullness", "index"}) -public class TreeMap +public @Modifiable class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index ad28363bbcac..6abb03f43d84 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -111,13 +111,13 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public class TreeSet extends AbstractSet +public @Modifiable class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { /** * The backing map. */ - private transient NavigableMap m; + private transient @Modifiable NavigableMap m; // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 7c7ddcd48add..440834d94de4 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -110,7 +111,7 @@ */ @CFComment({"lock/nullness: permits nullable object"}) @AnnotatedFor({"lock", "nullness", "index"}) -public class Vector +public @Modifiable class Vector extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @@ -159,7 +160,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public Vector(@NonNegative int initialCapacity, int capacityIncrement) { + public @Modifiable Vector(@NonNegative int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ @@ -176,7 +177,7 @@ public Vector(@NonNegative int initialCapacity, int capacityIncrement) { * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public Vector(@NonNegative int initialCapacity) { + public @Modifiable Vector(@NonNegative int initialCapacity) { this(initialCapacity, 0); } @@ -185,7 +186,7 @@ public Vector(@NonNegative int initialCapacity) { * has size {@code 10} and its standard capacity increment is * zero. */ - public Vector() { + public @Modifiable Vector() { this(10); } @@ -199,7 +200,7 @@ public Vector() { * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); elementCount = a.length; if (c.getClass() == ArrayList.class) { From 90ad64af95ef1627928ce8f0c778ba8f5512d25b Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 21 Jan 2026 18:36:47 -0800 Subject: [PATCH 008/119] annotated @WillThrowUOE --- src/java.base/share/classes/java/util/SortedMap.java | 3 +++ src/java.base/share/classes/java/util/SortedSet.java | 3 +++ src/java.base/share/classes/java/util/TreeMap.java | 3 +++ src/java.base/share/classes/java/util/TreeSet.java | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 38dd78b2920c..9a9605bc6eba 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -313,6 +314,7 @@ public interface SortedMap extends SequencedMap { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE default V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -328,6 +330,7 @@ default V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE default V putLast(K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 31b1820d4b85..a23d7c68db88 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; @@ -291,6 +292,7 @@ public Comparator getComparator() { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE default void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -306,6 +308,7 @@ default void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE default void addLast(E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 4064a2092613..901afedb715f 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -342,6 +343,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -354,6 +356,7 @@ public V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public V putLast(K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 6abb03f43d84..4a8662e1fc35 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -507,6 +508,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -519,6 +521,7 @@ public void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public void addLast(E e) { throw new UnsupportedOperationException(); } From d2cd4e98a29b64eb49f0600dccb9aaef84f93a74 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 22 Jan 2026 00:04:01 -0800 Subject: [PATCH 009/119] finished annotation on sequenced collections --- .../classes/java/util/SequencedCollection.java | 11 +++++++---- .../share/classes/java/util/SequencedMap.java | 10 ++++++---- .../share/classes/java/util/SortedMap.java | 10 ++++++---- .../share/classes/java/util/SortedSet.java | 13 +++++++------ 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 54237c7a3f77..0eae7eab4cc0 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -25,6 +25,9 @@ package java.util; + +import org.checkerframework.checker.modifiability.qual.Modifiable; + /** * A collection that has a well-defined encounter order, that supports operations at both ends, * and that is reversible. The elements of a sequenced collection have an @@ -103,7 +106,7 @@ public interface SequencedCollection extends Collection { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default void addFirst(E e) { + default void addFirst(@Modifiable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -121,7 +124,7 @@ default void addFirst(E e) { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default void addLast(E e) { + default void addLast(@Modifiable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -172,7 +175,7 @@ default E getLast() { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default E removeFirst() { + default E removeFirst(@Modifiable SequencedCollection this) { var it = this.iterator(); E e = it.next(); it.remove(); @@ -194,7 +197,7 @@ default E removeFirst() { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default E removeLast() { + default E removeLast(@Modifiable SequencedCollection this) { var it = this.reversed().iterator(); E e = it.next(); it.remove(); diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 6bff204b65dc..0711dffb79a6 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -27,6 +27,8 @@ import jdk.internal.util.NullableKeyValueHolder; +import org.checkerframework.checker.modifiability.qual.Modifiable; + /** * A Map that has a well-defined encounter order, that supports operations at both ends, and * that is reversible. The encounter order @@ -184,7 +186,7 @@ default Map.Entry lastEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default Map.Entry pollFirstEntry() { + default Map.Entry pollFirstEntry(@Modifiable SequencedMap this) { var it = entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); @@ -209,7 +211,7 @@ default Map.Entry pollFirstEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default Map.Entry pollLastEntry() { + default Map.Entry pollLastEntry(@Modifiable SequencedMap this) { var it = reversed().entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); @@ -235,7 +237,7 @@ default Map.Entry pollLastEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default V putFirst(K k, V v) { + default V putFirst(@Modifiable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -254,7 +256,7 @@ default V putFirst(K k, V v) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default V putLast(K k, V v) { + default V putLast(@Modifiable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 9a9605bc6eba..cd527454d7fb 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,6 +26,8 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; @@ -165,7 +167,7 @@ public interface SortedMap extends SequencedMap { * outside the bounds of the range */ @SideEffectFree - SortedMap subMap(@GuardSatisfied SortedMap this, @GuardSatisfied K fromKey, @GuardSatisfied K toKey); + @PolyModifiable SortedMap subMap(@PolyModifiable @GuardSatisfied SortedMap this, @GuardSatisfied K fromKey, @GuardSatisfied K toKey); /** * Returns a view of the portion of this map whose keys are @@ -193,7 +195,7 @@ public interface SortedMap extends SequencedMap { * bounds of the range */ @SideEffectFree - SortedMap headMap(@GuardSatisfied SortedMap this, K toKey); + @PolyModifiable SortedMap headMap(@PolyModifiable @GuardSatisfied SortedMap this, K toKey); /** * Returns a view of the portion of this map whose keys are @@ -221,7 +223,7 @@ public interface SortedMap extends SequencedMap { * bounds of the range */ @SideEffectFree - SortedMap tailMap(@GuardSatisfied SortedMap this, K fromKey); + @PolyModifiable SortedMap tailMap(@PolyModifiable @GuardSatisfied SortedMap this, K fromKey); /** * Returns the first (lowest) key currently in this map. @@ -345,7 +347,7 @@ default V putLast(K k, V v) { * @return a reverse-ordered view of this map, as a {@code SortedMap} * @since 21 */ - default SortedMap reversed() { + default @PolyModifiable SortedMap reversed(@PolyModifiable SortedMap this) { return ReverseOrderSortedMapView.of(this); } } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index a23d7c68db88..375793aece47 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; @@ -161,7 +162,7 @@ public interface SortedSet extends Set, SequencedSet { * {@code toElement} lies outside the bounds of the range */ @SideEffectFree - SortedSet subSet(@GuardSatisfied SortedSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement); + @PolyModifiable SortedSet subSet(@PolyModifiable @GuardSatisfied SortedSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement); /** * Returns a view of the portion of this set whose elements are @@ -189,7 +190,7 @@ public interface SortedSet extends Set, SequencedSet { * bounds of the range */ @SideEffectFree - SortedSet headSet(@GuardSatisfied SortedSet this, E toElement); + @PolyModifiable SortedSet headSet(@PolyModifiable @GuardSatisfied SortedSet this, E toElement); /** * Returns a view of the portion of this set whose elements are @@ -217,7 +218,7 @@ public interface SortedSet extends Set, SequencedSet { * bounds of the range */ @SideEffectFree - SortedSet tailSet(@GuardSatisfied SortedSet this, E fromElement); + @PolyModifiable SortedSet tailSet(@PolyModifiable @GuardSatisfied SortedSet this, E fromElement); /** * Returns the first (lowest) element currently in this set. @@ -351,7 +352,7 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeFirst() { + default E removeFirst(@Modifiable SortedSet this) { E e = this.first(); this.remove(e); return e; @@ -369,7 +370,7 @@ default E removeFirst() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeLast() { + default E removeLast(@Modifiable SortedSet this) { E e = this.last(); this.remove(e); return e; @@ -385,7 +386,7 @@ default E removeLast() { * @return a reverse-ordered view of this collection, as a {@code SortedSet} * @since 21 */ - default SortedSet reversed() { + default @PolyModifiable SortedSet reversed(@PolyModifiable SortedSet this) { return ReverseOrderSortedSetView.of(this); } } From 39c448a842d582adbd206cca1e12d1c0a8a17b36 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 22 Jan 2026 00:20:07 -0800 Subject: [PATCH 010/119] finished navigablemap and navigableset --- .../share/classes/java/util/NavigableMap.java | 22 +++++++++------- .../share/classes/java/util/NavigableSet.java | 26 ++++++++++--------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 6fd455e0255d..0be4c50a797b 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,6 +36,8 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.lock.qual.Modifiable; +import org.checkerframework.checker.lock.qual.PolyModifiable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -251,7 +253,7 @@ public interface NavigableMap extends SortedMap { * @return the removed first entry of this map, * or {@code null} if this map is empty */ - Map.@Nullable Entry pollFirstEntry(@GuardSatisfied NavigableMap this); + Map.@Nullable Entry pollFirstEntry(@Modifiable @GuardSatisfied NavigableMap this); /** * Removes and returns a key-value mapping associated with @@ -260,7 +262,7 @@ public interface NavigableMap extends SortedMap { * @return the removed last entry of this map, * or {@code null} if this map is empty */ - Map.@Nullable Entry pollLastEntry(@GuardSatisfied NavigableMap this); + Map.@Nullable Entry pollLastEntry(@Modifiable @GuardSatisfied NavigableMap this); /** * Returns a reverse order view of the mappings contained in this map. @@ -278,7 +280,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order view of this map */ @SideEffectFree - NavigableMap descendingMap(); + @PolyModifiable NavigableMap descendingMap(@PolyModifiable NavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -349,7 +351,7 @@ public interface NavigableMap extends SortedMap { * outside the bounds of the range */ @SideEffectFree - NavigableMap subMap(K fromKey, boolean fromInclusive, + @PolyModifiable NavigableMap subMap(@PolyModifiable NavigableMap this, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive); /** @@ -380,7 +382,7 @@ NavigableMap subMap(K fromKey, boolean fromInclusive, * bounds of the range */ @SideEffectFree - NavigableMap headMap(K toKey, boolean inclusive); + @PolyModifiable NavigableMap headMap(@PolyModifiable NavigableMap this, K toKey, boolean inclusive); /** * Returns a view of the portion of this map whose keys are greater than (or @@ -410,7 +412,7 @@ NavigableMap subMap(K fromKey, boolean fromInclusive, * bounds of the range */ @SideEffectFree - NavigableMap tailMap(K fromKey, boolean inclusive); + @PolyModifiable NavigableMap tailMap(@PolyModifiable NavigableMap this, K fromKey, boolean inclusive); /** * {@inheritDoc} @@ -422,7 +424,7 @@ NavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - SortedMap subMap(K fromKey, K toKey); + @PolyModifiable SortedMap subMap(@PolyModifiable NavigableMap this, K fromKey, K toKey); /** * {@inheritDoc} @@ -434,7 +436,7 @@ NavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - SortedMap headMap(K toKey); + @PolyModifiable SortedMap headMap(@PolyModifiable NavigableMap this, K toKey); /** * {@inheritDoc} @@ -446,7 +448,7 @@ NavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - SortedMap tailMap(K fromKey); + @PolyModifiable SortedMap tailMap(@PolyModifiable NavigableMap this, K fromKey); /** * {@inheritDoc} @@ -460,7 +462,7 @@ NavigableMap subMap(K fromKey, boolean fromInclusive, * @return a reverse-ordered view of this map, as a {@code NavigableMap} * @since 21 */ - default NavigableMap reversed() { + default @PolyModifiable NavigableMap reversed(@PolyModifiable NavigableMap this) { return this.descendingMap(); } } diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 3bcdf1879201..705644210f64 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -37,6 +37,8 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -176,7 +178,7 @@ public interface NavigableSet extends SortedSet { * @return an iterator over the elements in this set, in ascending order */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty NavigableSet this); + @PolyModifiable@PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet this); /** * Returns a reverse order view of the elements contained in this set. @@ -193,7 +195,7 @@ public interface NavigableSet extends SortedSet { * * @return a reverse order view of this set */ - NavigableSet descendingSet(); + @PolyModifiable NavigableSet descendingSet(@PolyModifiable NavigableSet this); /** * Returns an iterator over the elements in this set, in descending order. @@ -201,7 +203,7 @@ public interface NavigableSet extends SortedSet { * * @return an iterator over the elements in this set, in descending order */ - Iterator descendingIterator(); + @PolyModifiable Iterator descendingIterator(@PolyModifiable NavigableSet this); /** * Returns a view of the portion of this set whose elements range from @@ -239,7 +241,7 @@ public interface NavigableSet extends SortedSet { * {@code toElement} lies outside the bounds of the range. */ @SideEffectFree - NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E fromElement, boolean fromInclusive, + @PolyModifiable NavigableSet subSet(@PolyModifiable NavigableSet this, @GuardSatisfied E fromElement, boolean fromInclusive, @GuardSatisfied E toElement, boolean toInclusive); /** @@ -270,7 +272,7 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * bounds of the range */ @SideEffectFree - NavigableSet headSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E toElement, boolean inclusive); + @PolyModifiable NavigableSet headSet(@PolyModifiable NavigableSet this, @GuardSatisfied E toElement, boolean inclusive); /** * Returns a view of the portion of this set whose elements are greater @@ -300,7 +302,7 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * bounds of the range */ @SideEffectFree - NavigableSet tailSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E fromElement, boolean inclusive); + @PolyModifiable NavigableSet tailSet(@PolyModifiable NavigableSet this, @GuardSatisfied E fromElement, boolean inclusive); /** * {@inheritDoc} @@ -312,7 +314,7 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - SortedSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement); + @PolyModifiable SortedSet subSet(@PolyModifiable NavigableSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement); /** * {@inheritDoc} @@ -324,7 +326,7 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - SortedSet headSet(@GuardSatisfied NavigableSet this, E toElement); + @PolyModifiable SortedSet headSet(@PolyModifiable NavigableSet this, E toElement); /** * {@inheritDoc} @@ -336,7 +338,7 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - SortedSet tailSet(@GuardSatisfied NavigableSet this, E fromElement); + @PolyModifiable SortedSet tailSet(@PolyModifiable NavigableSet this, E fromElement); /** * {@inheritDoc} @@ -349,7 +351,7 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeFirst() { + default E removeFirst(@Modifiable NavigableSet this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { @@ -368,7 +370,7 @@ default E removeFirst() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeLast() { + default E removeLast(@Modifiable NavigableSet this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { @@ -388,7 +390,7 @@ default E removeLast() { * @return a reverse-ordered view of this collection, as a {@code NavigableSet} * @since 21 */ - default NavigableSet reversed() { + default @PolyModifiable NavigableSet reversed(@PolyModifiable NavigableSet this) { return this.descendingSet(); } } From c6c5e477593ca65b10af78f2081f0fb1f66ef941 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 22 Jan 2026 13:51:17 -0800 Subject: [PATCH 011/119] finished annotation on ConcurrentMap and ConcurrentNavigableMap --- .../java/util/concurrent/ConcurrentMap.java | 24 ++++++++++--------- .../concurrent/ConcurrentNavigableMap.java | 21 ++++++++++------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 018492522c1a..5a31abfcd266 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -36,6 +36,8 @@ package java.util.concurrent; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiable; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -93,7 +95,7 @@ public interface ConcurrentMap this,Object key, V defaultValue) { V v; return ((v = get(key)) != null) ? v : defaultValue; } @@ -117,7 +119,7 @@ default V getOrDefault(Object key, V defaultValue) { * @since 1.8 */ @Override - default void forEach(BiConsumer action) { + default void forEach(@UnknownModifiable ConcurrentMap this,BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { K k; @@ -165,7 +167,7 @@ default void forEach(BiConsumer action) { * or value prevents it from being stored in this map */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - @Nullable V putIfAbsent(K key, V value); + @Nullable V putIfAbsent(@Modifiable ConcurrentMap this, K key, V value); /** * Removes the entry for a key only if currently mapped to a given value. @@ -196,7 +198,7 @@ default void forEach(BiConsumer action) { * and this map does not permit null keys or values * (optional) */ - boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value); + boolean remove(@Modifiable ConcurrentMap this, @UnknownSignedness Object key, @UnknownSignedness Object value); /** * Replaces the entry for a key only if currently mapped to a given value. @@ -228,7 +230,7 @@ default void forEach(BiConsumer action) { * @throws IllegalArgumentException if some property of a specified key * or value prevents it from being stored in this map */ - boolean replace(K key, V oldValue, V newValue); + boolean replace(@Modifiable ConcurrentMap this, K key, V oldValue, V newValue); /** * Replaces the entry for a key only if currently mapped to some value. @@ -260,7 +262,7 @@ default void forEach(BiConsumer action) { * @throws IllegalArgumentException if some property of the specified key * or value prevents it from being stored in this map */ - @Nullable V replace(K key, V value); + @Nullable V replace(@Modifiable ConcurrentMap this, K key, V value); /** * {@inheritDoc} @@ -293,7 +295,7 @@ default void forEach(BiConsumer action) { * @since 1.8 */ @Override - default void replaceAll(BiFunction function) { + default void replaceAll(@Modifiable ConcurrentMap this, BiFunction function) { Objects.requireNonNull(function); forEach((k,v) -> { while (!replace(k, v, function.apply(k, v))) { @@ -333,7 +335,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @Override - default @PolyNull V computeIfAbsent(K key, + default @PolyNull V computeIfAbsent(@Modifiable ConcurrentMap this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V oldValue, newValue; @@ -375,7 +377,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @Override - default @PolyNull V computeIfPresent(K key, + default @PolyNull V computeIfPresent(@Modifiable ConcurrentMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); for (V oldValue; (oldValue = get(key)) != null; ) { @@ -423,7 +425,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @Override - default @PolyNull V compute(K key, + default @PolyNull V compute(@Modifiable ConcurrentMap this, K key, BiFunction remappingFunction) { retry: for (;;) { V oldValue = get(key); @@ -483,7 +485,7 @@ else if ((oldValue = putIfAbsent(key, newValue)) == null) * @since 1.8 */ @Override - default @PolyNull V merge(K key, @NonNull V value, + default @PolyNull V merge(@Modifiable ConcurrentMap this, K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index f201d63bcb85..fe8eb9969bd0 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -35,6 +35,7 @@ package java.util.concurrent; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.NavigableMap; @@ -62,7 +63,8 @@ public interface ConcurrentNavigableMap * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, + @PolyModifiable ConcurrentNavigableMap subMap(@PolyModifiable ConcurrentNavigableMap this, + K fromKey, boolean fromInclusive, K toKey, boolean toInclusive); /** @@ -71,7 +73,8 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - ConcurrentNavigableMap headMap(K toKey, boolean inclusive); + @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentNavigableMap this, + K toKey, boolean inclusive); /** * @throws ClassCastException {@inheritDoc} @@ -79,7 +82,8 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - ConcurrentNavigableMap tailMap(K fromKey, boolean inclusive); + @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentNavigableMap this, + K fromKey, boolean inclusive); /** * @throws ClassCastException {@inheritDoc} @@ -87,7 +91,8 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - ConcurrentNavigableMap subMap(K fromKey, K toKey); + @PolyModifiable ConcurrentNavigableMap subMap(@PolyModifiable ConcurrentNavigableMap this, + K fromKey, K toKey); /** * @throws ClassCastException {@inheritDoc} @@ -95,7 +100,8 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - ConcurrentNavigableMap headMap(K toKey); + @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentNavigableMap this, + K toKey); /** * @throws ClassCastException {@inheritDoc} @@ -103,7 +109,8 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - ConcurrentNavigableMap tailMap(K fromKey); + @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentNavigableMap this, + K fromKey); /** * Returns a reverse order view of the mappings contained in this map. @@ -118,7 +125,7 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * @return a reverse order view of this map */ @SideEffectFree - ConcurrentNavigableMap descendingMap(); + @PolyModifiable ConcurrentNavigableMap descendingMap(@PolyModifiable ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. From 93a16b447da249998d2fb2e404c5c87861ba6dfa Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 22 Jan 2026 14:02:30 -0800 Subject: [PATCH 012/119] added unmod annotations for sequenced collections --- src/java.base/share/classes/java/util/Collections.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index ba4e7e8c89e3..8be1aa8d3d53 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -1217,7 +1217,7 @@ public Stream parallelStream() { * @since 21 */ @SuppressWarnings("unchecked") - public static SequencedCollection unmodifiableSequencedCollection(SequencedCollection c) { + public static @Unmodifiable SequencedCollection unmodifiableSequencedCollection(SequencedCollection c) { if (c.getClass() == UnmodifiableSequencedCollection.class) { return (SequencedCollection) c; } @@ -1328,7 +1328,7 @@ static class UnmodifiableSet extends UnmodifiableCollection * @since 21 */ @SuppressWarnings("unchecked") - public static SequencedSet unmodifiableSequencedSet(SequencedSet s) { + public static @Unmodifiable SequencedSet unmodifiableSequencedSet(SequencedSet s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSequencedSet.class) { return (SequencedSet) s; @@ -2062,7 +2062,7 @@ && eq(e.getKey(), t.getKey()) * @since 21 */ @SuppressWarnings("unchecked") - public static SequencedMap unmodifiableSequencedMap(SequencedMap m) { + public static @Unmodifiable SequencedMap unmodifiableSequencedMap(SequencedMap m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableSequencedMap.class) { return (SequencedMap) m; From 1df9393155a171f3d07fa09bf78a65ab84dd9391 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 22 Jan 2026 14:52:35 -0800 Subject: [PATCH 013/119] fixed some annotations --- src/java.base/share/classes/java/util/Arrays.java | 3 ++- src/java.base/share/classes/java/util/Hashtable.java | 3 ++- src/java.base/share/classes/java/util/List.java | 8 ++++---- src/java.base/share/classes/java/util/NavigableMap.java | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index e8c55ba81a54..f425b39811a2 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.index.qual.SearchIndexFor; import org.checkerframework.checker.interning.qual.PolyInterned; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.mustcall.qual.MustCallUnknown; import org.checkerframework.checker.mustcall.qual.PolyMustCall; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -4273,7 +4274,7 @@ private static boolean[] copyOfRangeBoolean(boolean[] original, int from, int to @SafeVarargs @SideEffectFree @SuppressWarnings("varargs") - public static @PolyNonEmpty List asList(T @PolyNonEmpty... a) { + public static @Modifiable @PolyNonEmpty List asList(T @PolyNonEmpty... a) { return new ArrayList<>(a); } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index dac8d241449f..ea3062654645 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -152,7 +153,7 @@ */ @CFComment({"lock: This collection can only contain nonnull values"}) @AnnotatedFor({"lock", "nullness", "index"}) -public class Hashtable +public @Modifiable class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 5512b78cf524..e6ab42cfe94d 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -848,7 +848,7 @@ default Spliterator spliterator() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default void addFirst(E e) { + default void addFirst(@Modifiable List this, E e) { this.add(0, e); } @@ -862,7 +862,7 @@ default void addFirst(E e) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default void addLast(E e) { + default void addLast(@Modifiable List this, E e) { this.add(e); } @@ -913,7 +913,7 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeFirst() { + default E removeFirst(@Modifiable List this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { @@ -932,7 +932,7 @@ default E removeFirst() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeLast() { + default E removeLast(@Modifiable List this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 0be4c50a797b..7835c8504be5 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,8 +36,8 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.lock.qual.Modifiable; -import org.checkerframework.checker.lock.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; From 266330c2be546f1e77825a9e79d3663db59759ca Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 25 Jan 2026 17:36:01 -0800 Subject: [PATCH 014/119] annotated the abstract interfaces. --- .../classes/java/util/AbstractCollection.java | 35 ++++++++++-------- .../share/classes/java/util/AbstractList.java | 36 ++++++++++--------- .../share/classes/java/util/AbstractMap.java | 31 ++++++++-------- .../java/util/AbstractSequentialList.java | 17 +++++---- .../share/classes/java/util/AbstractSet.java | 8 +++-- 5 files changed, 72 insertions(+), 55 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 87cc5edd01de..f46c08867ece 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -29,6 +29,12 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; @@ -96,10 +102,9 @@ protected AbstractCollection() { * @return an iterator over the elements contained in this collection */ @SideEffectFree - public abstract @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractCollection this); - + public abstract @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractCollection this); @Pure - public abstract @NonNegative int size(@GuardSatisfied AbstractCollection this); + public abstract @NonNegative int size(@UnknownModifiability @GuardSatisfied AbstractCollection this); /** * {@inheritDoc} @@ -109,7 +114,7 @@ protected AbstractCollection() { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - public boolean isEmpty(@GuardSatisfied AbstractCollection this) { + public boolean isEmpty(@UnknownModifiability @GuardSatisfied AbstractCollection this) { return size() == 0; } @@ -125,7 +130,7 @@ public boolean isEmpty(@GuardSatisfied AbstractCollection this) { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean contains(@UnknownModifiability @GuardSatisfied AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) @@ -163,7 +168,7 @@ public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisf * } */ @SideEffectFree - public @PolyNull @PolySigned Object[] toArray(AbstractCollection<@PolyNull @PolySigned E> this) { + public @PolyNull @PolySigned Object[] toArray(@UnknownModifiability AbstractCollection<@PolyNull @PolySigned E> this) { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator it = iterator(); @@ -205,7 +210,7 @@ public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisf */ @SideEffectFree @SuppressWarnings("unchecked") - public @Nullable T [] toArray(@PolyNull T [] a) { + public @Nullable T [] toArray(@UnknownModifiability @PolyNull T [] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : @@ -275,7 +280,7 @@ private static T[] finishToArray(T[] r, Iterator it) { * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ - public boolean add(@GuardSatisfied AbstractCollection this, E e) { + public boolean add(@Modifiable @GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); } @@ -296,7 +301,7 @@ public boolean add(@GuardSatisfied AbstractCollection this, E e) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public boolean remove(@GuardSatisfied @Shrinkable AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@Modifiable @GuardSatisfied @Shrinkable AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) { @@ -333,7 +338,7 @@ public boolean remove(@GuardSatisfied @Shrinkable AbstractCollection this, @G * @see #contains(Object) */ @Pure - public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSatisfied Collection c) { + public boolean containsAll(@UnknownModifiability @GuardSatisfied AbstractCollection this, @GuardSatisfied Collection c) { for (Object e : c) if (!contains(e)) return false; @@ -359,7 +364,7 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat * * @see #add(Object) */ - public boolean addAll(@GuardSatisfied AbstractCollection this, Collection c) { + public boolean addAll(@Modifiable @GuardSatisfied AbstractCollection this, Collection c) { boolean modified = false; for (E e : c) if (add(e)) @@ -389,7 +394,7 @@ public boolean addAll(@GuardSatisfied AbstractCollection this, Collection this, Collection c) { + public boolean removeAll(@Modifiable @GuardSatisfied @Shrinkable AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -424,7 +429,7 @@ public boolean removeAll(@GuardSatisfied @Shrinkable AbstractCollection this, * @see #remove(Object) * @see #contains(Object) */ - public boolean retainAll(@GuardSatisfied @Shrinkable AbstractCollection this, Collection c) { + public boolean retainAll(@Modifiable @GuardSatisfied @Shrinkable AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -453,7 +458,7 @@ public boolean retainAll(@GuardSatisfied @Shrinkable AbstractCollection this, * * @throws UnsupportedOperationException {@inheritDoc} */ - public void clear(@GuardSatisfied @Shrinkable AbstractCollection this) { + public void clear(@Modifiable @GuardSatisfied @Shrinkable AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { it.next(); @@ -475,7 +480,7 @@ public void clear(@GuardSatisfied @Shrinkable AbstractCollection this) { * @return a string representation of this collection */ @SideEffectFree - public String toString(@GuardSatisfied AbstractCollection this) { + public String toString(@UnknownModifiability @GuardSatisfied AbstractCollection this) { Iterator it = iterator(); if (! it.hasNext()) return "[]"; diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index cd389c4c4d90..7b5f2409dfcf 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -31,6 +31,10 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -131,7 +135,7 @@ protected AbstractList() { * prevents it from being added to this list */ @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied AbstractList this, E e) { + public boolean add(@Modifiable @GuardSatisfied AbstractList this, E e) { add(size(), e); return true; } @@ -142,7 +146,7 @@ public boolean add(@GuardSatisfied AbstractList this, E e) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Pure - public abstract E get(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index); + public abstract E get(@UnknownModifiability @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index); /** * {@inheritDoc} @@ -157,7 +161,7 @@ public boolean add(@GuardSatisfied AbstractList this, E e) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { + public E set(@Modifiable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -174,7 +178,7 @@ public E set(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(@GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { + public void add(@Modifiable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -188,7 +192,7 @@ public void add(@GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@GuardSatisfied @Shrinkable AbstractList this, @IndexFor({"this"}) int index) { + public E remove(@Modifiable @GuardSatisfied @Shrinkable AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); } @@ -207,7 +211,7 @@ public E remove(@GuardSatisfied @Shrinkable AbstractList this, @IndexFor({"th * @throws NullPointerException {@inheritDoc} */ @Pure - public @GTENegativeOne int indexOf(@GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { + public @GTENegativeOne int indexOf(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(); if (o==null) { while (it.hasNext()) @@ -234,7 +238,7 @@ public E remove(@GuardSatisfied @Shrinkable AbstractList this, @IndexFor({"th * @throws NullPointerException {@inheritDoc} */ @Pure - public @GTENegativeOne int lastIndexOf(@GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { + public @GTENegativeOne int lastIndexOf(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(size()); if (o==null) { while (it.hasPrevious()) @@ -266,7 +270,7 @@ public E remove(@GuardSatisfied @Shrinkable AbstractList this, @IndexFor({"th * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ - public void clear(@GuardSatisfied @Shrinkable AbstractList this) { + public void clear(@Modifiable @GuardSatisfied @Shrinkable AbstractList this) { removeRange(0, size()); } @@ -290,7 +294,7 @@ public void clear(@GuardSatisfied @Shrinkable AbstractList this) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public boolean addAll(@GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { + public boolean addAll(@Modifiable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { @@ -323,7 +327,7 @@ public boolean addAll(@GuardSatisfied AbstractList this, @IndexOrHigh({"this" * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractList this) { return new Itr(); } @@ -335,7 +339,7 @@ public boolean addAll(@GuardSatisfied AbstractList this, @IndexOrHigh({"this" * * @see #listIterator(int) */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractList this) { return listIterator(0); } @@ -362,7 +366,7 @@ public boolean addAll(@GuardSatisfied AbstractList this, @IndexOrHigh({"this" * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink AbstractList this, final @IndexOrHigh({"this"}) int index) { + public @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink AbstractList this, final @IndexOrHigh({"this"}) int index) { rangeCheckForAdd(index); return new ListItr(index); @@ -525,7 +529,7 @@ public void add(E e) { * {@code (fromIndex > toIndex)} */ @SideEffectFree - public @PolyGrowShrink List subList(@GuardSatisfied @PolyGrowShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + public @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { subListRangeCheck(fromIndex, toIndex, size()); return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : @@ -567,7 +571,7 @@ static void subListRangeCheck(int fromIndex, int toIndex, int size) { * @return {@code true} if the specified object is equal to this list */ @Pure - public boolean equals(@GuardSatisfied AbstractList this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; if (!(o instanceof List)) @@ -595,7 +599,7 @@ public boolean equals(@GuardSatisfied AbstractList this, @GuardSatisfied @Nul * @return the hash code value for this list */ @Pure - public int hashCode(@GuardSatisfied AbstractList this) { + public int hashCode(@UnknownModifiability @GuardSatisfied AbstractList this) { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); @@ -625,7 +629,7 @@ public int hashCode(@GuardSatisfied AbstractList this) { * @param fromIndex index of first element to be removed * @param toIndex index after last element to be removed */ - protected void removeRange(@GuardSatisfied @Shrinkable AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + protected void removeRange(@Modifiable @GuardSatisfied @Shrinkable AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i this) { + public @NonNegative int size(@UnknownModifiability @GuardSatisfied AbstractMap this) { return entrySet().size(); } @@ -117,7 +120,7 @@ protected AbstractMap() { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - public boolean isEmpty(@GuardSatisfied AbstractMap this) { + public boolean isEmpty(@UnknownModifiability @GuardSatisfied AbstractMap this) { return size() == 0; } @@ -135,7 +138,7 @@ public boolean isEmpty(@GuardSatisfied AbstractMap this) { * @throws NullPointerException {@inheritDoc} */ @Pure - public boolean containsValue(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object value) { + public boolean containsValue(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object value) { Iterator> i = entrySet().iterator(); if (value==null) { while (i.hasNext()) { @@ -169,7 +172,7 @@ public boolean containsValue(@GuardSatisfied AbstractMap this, @GuardSatis */ @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure - public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { @@ -202,7 +205,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi * @throws NullPointerException {@inheritDoc} */ @Pure - public @Nullable V get(@GuardSatisfied AbstractMap this, @UnknownSignedness @GuardSatisfied Object key) { + public @Nullable V get(@UnknownModifiability @GuardSatisfied AbstractMap this, @UnknownSignedness @GuardSatisfied Object key) { Iterator> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { @@ -237,7 +240,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi */ @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(@GuardSatisfied AbstractMap this, K key, V value) { + public @Nullable V put(@Modifiable @GuardSatisfied AbstractMap this, K key, V value) { throw new UnsupportedOperationException(); } @@ -263,7 +266,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public @Nullable V remove(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + public @Nullable V remove(@Modifiable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); Entry correctEntry = null; if (key==null) { @@ -308,7 +311,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public void putAll(@GuardSatisfied AbstractMap this, Map m) { + public void putAll(@Modifiable @GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); } @@ -325,7 +328,7 @@ public void putAll(@GuardSatisfied AbstractMap this, Map this) { + public void clear(@Modifiable @GuardSatisfied AbstractMap this) { entrySet().clear(); } @@ -522,7 +525,7 @@ public boolean contains(@UnknownSignedness Object v) { * @return {@code true} if the specified object is equal to this map */ @Pure - public boolean equals(@GuardSatisfied AbstractMap this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; @@ -569,7 +572,7 @@ public boolean equals(@GuardSatisfied AbstractMap this, @GuardSatisfied @N * @see Set#equals(Object) */ @Pure - public int hashCode(@GuardSatisfied AbstractMap this) { + public int hashCode(@UnknownModifiability@GuardSatisfied AbstractMap this) { int h = 0; for (Entry entry : entrySet()) h += entry.hashCode(); @@ -589,7 +592,7 @@ public int hashCode(@GuardSatisfied AbstractMap this) { * @return a string representation of this map */ @SideEffectFree - public String toString(@GuardSatisfied AbstractMap this) { + public String toString(@UnknownModifiability @GuardSatisfied AbstractMap this) { Iterator> i = entrySet().iterator(); if (! i.hasNext()) return "{}"; @@ -657,7 +660,7 @@ private static boolean eq(Object o1, Object o2) { * * @since 1.6 */ - public static class SimpleEntry + public static @Modifiable class SimpleEntry implements Entry, java.io.Serializable { @java.io.Serial @@ -808,7 +811,7 @@ public String toString(AbstractMap.@GuardSatisfied SimpleEntry this) { * @param the type of the value * @since 1.6 */ - public static class SimpleImmutableEntry + public static @Unmodifiable class SimpleImmutableEntry implements Entry, java.io.Serializable { @java.io.Serial diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index dfa76cdf439a..7761739624d5 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -28,6 +28,9 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +Import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -97,7 +100,7 @@ protected AbstractSequentialList() { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Pure - public E get(@GuardSatisfied AbstractSequentialList this, int index) { + public E get(@UnknownModifiability @GuardSatisfied AbstractSequentialList this, int index) { try { return listIterator(index).next(); } catch (NoSuchElementException exc) { @@ -124,7 +127,7 @@ public E get(@GuardSatisfied AbstractSequentialList this, int index) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(@GuardSatisfied AbstractSequentialList this, int index, E element) { + public E set(@Modifiable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { ListIterator e = listIterator(index); E oldVal = e.next(); @@ -155,7 +158,7 @@ public E set(@GuardSatisfied AbstractSequentialList this, int index, E elemen * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(@GuardSatisfied AbstractSequentialList this, int index, E element) { + public void add(@Modifiable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { listIterator(index).add(element); } catch (NoSuchElementException exc) { @@ -180,7 +183,7 @@ public void add(@GuardSatisfied AbstractSequentialList this, int index, E ele * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@GuardSatisfied @Shrinkable AbstractSequentialList this, int index) { + public E remove(@Modifiable @GuardSatisfied @Shrinkable AbstractSequentialList this, int index) { try { ListIterator e = listIterator(index); E outCast = e.next(); @@ -223,7 +226,7 @@ public E remove(@GuardSatisfied @Shrinkable AbstractSequentialList this, int * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public boolean addAll(@GuardSatisfied AbstractSequentialList this, int index, Collection c) { + public boolean addAll(@Modifiable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { try { boolean modified = false; ListIterator e1 = listIterator(index); @@ -249,7 +252,7 @@ public boolean addAll(@GuardSatisfied AbstractSequentialList this, int index, * @return an iterator over the elements in this list (in proper sequence) */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractSequentialList this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractSequentialList this) { return listIterator(); } @@ -263,5 +266,5 @@ public boolean addAll(@GuardSatisfied AbstractSequentialList this, int index, * sequence) * @throws IndexOutOfBoundsException {@inheritDoc} */ - public abstract @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink AbstractSequentialList this, int index); + public abstract @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink AbstractSequentialList this, int index); } diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index a18723fbaca8..19e86415cd2d 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -26,6 +26,8 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; @@ -92,7 +94,7 @@ protected AbstractSet() { * @return {@code true} if the specified object is equal to this set */ @Pure - public boolean equals(@GuardSatisfied AbstractSet this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@UnknownModifiability @GuardSatisfied AbstractSet this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; @@ -126,7 +128,7 @@ public boolean equals(@GuardSatisfied AbstractSet this, @GuardSatisfied @Null * @see Set#equals(Object) */ @Pure - public int hashCode(@GuardSatisfied AbstractSet this) { + public int hashCode(@UnknownModifiability @GuardSatisfied AbstractSet this) { int h = 0; Iterator i = iterator(); while (i.hasNext()) { @@ -174,7 +176,7 @@ public int hashCode(@GuardSatisfied AbstractSet this) { * @see #remove(Object) * @see #contains(Object) */ - public boolean removeAll(@GuardSatisfied AbstractSet this, Collection c) { + public boolean removeAll(@Modifiable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; From bee62842b10fbdcade5756fd86e6c3b44576dee0 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 25 Jan 2026 17:36:54 -0800 Subject: [PATCH 015/119] fixed unknownmodifiability --- .../share/classes/java/util/concurrent/ConcurrentMap.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 5a31abfcd266..32286c17da65 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -95,7 +95,7 @@ public interface ConcurrentMap this,Object key, V defaultValue) { + default V getOrDefault(@UnknownModifiability ConcurrentMap this,Object key, V defaultValue) { V v; return ((v = get(key)) != null) ? v : defaultValue; } @@ -119,7 +119,7 @@ default V getOrDefault(@UnknownModifiable ConcurrentMap this,Object key, V * @since 1.8 */ @Override - default void forEach(@UnknownModifiable ConcurrentMap this,BiConsumer action) { + default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { K k; From 0ed3390e9d46972bf8bc6661f3c1edf8f5cd8c55 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 25 Jan 2026 18:23:09 -0800 Subject: [PATCH 016/119] finished basic annotations on queue --- .../share/classes/java/util/AbstractQueue.java | 3 ++- .../share/classes/java/util/ArrayDeque.java | 3 ++- .../share/classes/java/util/Deque.java | 17 ++++++++++------- .../share/classes/java/util/PriorityQueue.java | 3 ++- .../share/classes/java/util/Queue.java | 3 ++- .../java/util/concurrent/BlockingDeque.java | 3 ++- .../java/util/concurrent/BlockingQueue.java | 3 ++- .../java/util/concurrent/TransferQueue.java | 4 +++- 8 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index 5c991c3b784f..da06b3d2abd6 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.framework.qual.AnnotatedFor; @@ -68,7 +69,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"lock", "nullness"}) -public abstract class AbstractQueue +public @Modifiable abstract class AbstractQueue extends AbstractCollection implements Queue { diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index f564841142ae..f1c254fd3486 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -105,7 +106,7 @@ * @since 1.6 */ @AnnotatedFor({"lock", "nullness", "index"}) -public class ArrayDeque extends AbstractCollection +public @Modifiable class ArrayDeque extends AbstractCollection implements Deque, Cloneable, Serializable { /* diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 6d5901def3bc..7987b18aee93 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -39,6 +39,9 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -218,7 +221,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) -public interface Deque extends Queue, SequencedCollection { +public @Modifiable interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, @@ -237,7 +240,7 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - void addFirst(@GuardSatisfied Deque this, E e); + void addFirst(@Modifiable @GuardSatisfied Deque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -259,7 +262,7 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - void addLast(@GuardSatisfied Deque this, E e); + void addLast(@Modifiable @GuardSatisfied Deque this, E e); /** * Inserts the specified element at the front of this deque unless it would @@ -305,7 +308,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ - E removeFirst(@GuardSatisfied @NonEmpty @Shrinkable Deque this); + E removeFirst(@Modifiable @GuardSatisfied @NonEmpty @Shrinkable Deque this); /** * Retrieves and removes the last element of this deque. This method @@ -315,7 +318,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the tail of this deque * @throws NoSuchElementException if this deque is empty */ - E removeLast(@GuardSatisfied @NonEmpty @Shrinkable Deque this); + E removeLast(@Modifiable @GuardSatisfied @NonEmpty @Shrinkable Deque this); /** * Retrieves and removes the first element of this deque, @@ -323,7 +326,7 @@ public interface Deque extends Queue, SequencedCollection { * * @return the head of this deque, or {@code null} if this deque is empty */ - @Nullable E pollFirst(@GuardSatisfied @Shrinkable Deque this); + @Nullable E pollFirst(@Modifiable @GuardSatisfied @Shrinkable Deque this); /** * Retrieves and removes the last element of this deque, @@ -331,7 +334,7 @@ public interface Deque extends Queue, SequencedCollection { * * @return the tail of this deque, or {@code null} if this deque is empty */ - @Nullable E pollLast(@GuardSatisfied @Shrinkable Deque this); + @Nullable E pollLast(@Modifiable @GuardSatisfied @Shrinkable Deque this); /** * Retrieves, but does not remove, the first element of this deque. diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index f3b25d1c36e9..a90a469e4990 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -106,7 +107,7 @@ @CFComment({"lock/nullness: This class doesn't permits null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) @SuppressWarnings("unchecked") -public class PriorityQueue extends AbstractQueue +public @Modifiable class PriorityQueue extends AbstractQueue implements java.io.Serializable { @java.io.Serial diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index 425d93f9add9..2d1289c58973 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -147,7 +148,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public interface Queue extends Collection { +public @Modifiable interface Queue extends Collection { /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java index e40f9c72e2f7..97c3983194a2 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -210,7 +211,7 @@ * @param the type of elements held in this deque */ @AnnotatedFor({"nullness"}) -public interface BlockingDeque extends BlockingQueue, Deque { +public @Modifiable interface BlockingDeque extends BlockingQueue, Deque { /* * We have "diamond" multiple interface inheritance here, and that * introduces ambiguities. Methods might end up with different diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index 7ad116a16c34..11ff1c098fde 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -188,7 +189,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"nullness"}) -public interface BlockingQueue extends Queue { +public @Modifiable interface BlockingQueue extends Queue { /** * Inserts the specified element into this queue if it is possible to do * so immediately without violating capacity restrictions, returning diff --git a/src/java.base/share/classes/java/util/concurrent/TransferQueue.java b/src/java.base/share/classes/java/util/concurrent/TransferQueue.java index 72a4108e61b8..847c1a0bb73d 100644 --- a/src/java.base/share/classes/java/util/concurrent/TransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/TransferQueue.java @@ -35,6 +35,8 @@ package java.util.concurrent; +import org.checkerframework.checker.modifiability.qual.Modifiable; + /** * A {@link BlockingQueue} in which producers may wait for consumers * to receive elements. A {@code TransferQueue} may be useful for @@ -65,7 +67,7 @@ * @author Doug Lea * @param the type of elements held in this queue */ -public interface TransferQueue extends BlockingQueue { +public @Modifiable interface TransferQueue extends BlockingQueue { /** * Transfers the element to a waiting consumer immediately, if possible. * From 03685d366a133c948da6322c0433d16fa36119f8 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 26 Jan 2026 14:41:22 -0800 Subject: [PATCH 017/119] finished annotating queue --- .../classes/java/util/concurrent/ArrayBlockingQueue.java | 7 ++++--- .../share/classes/java/util/concurrent/BlockingQueue.java | 4 ++-- .../java/util/concurrent/ConcurrentLinkedQueue.java | 3 ++- .../share/classes/java/util/concurrent/DelayQueue.java | 7 ++++--- .../classes/java/util/concurrent/LinkedBlockingDeque.java | 7 ++++--- .../classes/java/util/concurrent/LinkedBlockingQueue.java | 7 ++++--- .../classes/java/util/concurrent/LinkedTransferQueue.java | 3 ++- .../java/util/concurrent/PriorityBlockingQueue.java | 7 ++++--- .../classes/java/util/concurrent/SynchronousQueue.java | 7 ++++--- 9 files changed, 30 insertions(+), 22 deletions(-) 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 af4055aa8ad8..2287da2b6334 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -100,7 +101,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"nullness"}) -public class ArrayBlockingQueue extends AbstractQueue +public @Modifiable class ArrayBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { /* @@ -717,7 +718,7 @@ private static void circularClear(Object[] items, int i, int end) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable ArrayBlockingQueue this, Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable ArrayBlockingQueue this, @Modifiable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -727,7 +728,7 @@ public int drainTo(@GuardSatisfied @Shrinkable ArrayBlockingQueue this, Colle * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable ArrayBlockingQueue this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable ArrayBlockingQueue this, @Modifiable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index 11ff1c098fde..9125b42cb3d1 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -362,7 +362,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ - int drainTo(@GuardSatisfied @Shrinkable BlockingQueue this, Collection c); + int drainTo(@GuardSatisfied @Shrinkable BlockingQueue this, @Modifiable Collection c); /** * Removes at most the given number of available elements from @@ -387,5 +387,5 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ - int drainTo(@GuardSatisfied @Shrinkable BlockingQueue this, Collection c, int maxElements); + int drainTo(@GuardSatisfied @Shrinkable BlockingQueue this, @Modifiable Collection c, int maxElements); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 92876af30e22..3541ae7184b6 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -124,7 +125,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"nullness"}) -public class ConcurrentLinkedQueue extends AbstractQueue +public @Modifiable class ConcurrentLinkedQueue extends AbstractQueue implements Queue, java.io.Serializable { private static final long serialVersionUID = 196745693267521676L; diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index fb27e12d8bff..6849739260df 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -35,6 +35,7 @@ package java.util.concurrent; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -114,7 +115,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"nullness"}) -public class DelayQueue extends AbstractQueue +public @Modifiable class DelayQueue extends AbstractQueue implements BlockingQueue { private final transient ReentrantLock lock = new ReentrantLock(); @@ -386,7 +387,7 @@ public int size() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable DelayQueue this, Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable DelayQueue this, @Modifiable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -396,7 +397,7 @@ public int drainTo(@GuardSatisfied @Shrinkable DelayQueue this, Collection this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable DelayQueue this, @Modifiable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); 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 2c5ecfbb033b..b50e340c71bb 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -92,7 +93,7 @@ * @param the type of elements held in this deque */ @AnnotatedFor({"nullness"}) -public class LinkedBlockingDeque +public @Modifiable class LinkedBlockingDeque extends AbstractQueue implements BlockingDeque, java.io.Serializable { @@ -743,7 +744,7 @@ public int remainingCapacity() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingDeque this, Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingDeque this, @Modifiable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -753,7 +754,7 @@ public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingDeque this, Coll * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingDeque this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingDeque this, @Modifiable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); 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 dc52c8b1cf8e..ff112766c1ca 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -94,7 +95,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"nullness"}) -public class LinkedBlockingQueue extends AbstractQueue +public @Modifiable class LinkedBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = -6903933977591709194L; @@ -705,7 +706,7 @@ public void clear(@GuardSatisfied @Shrinkable LinkedBlockingQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingQueue this, Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingQueue this, @Modifiable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -715,7 +716,7 @@ public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingQueue this, Coll * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingQueue this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable LinkedBlockingQueue this, @Modifiable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 31d4ad306996..514c04a9b5b1 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -103,7 +104,7 @@ * @author Doug Lea * @param the type of elements held in this queue */ -public class LinkedTransferQueue extends AbstractQueue +public @Modifiable class LinkedTransferQueue extends AbstractQueue implements TransferQueue, java.io.Serializable { private static final long serialVersionUID = -3223113410248163686L; 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 bbc80761c7f0..1472cb005c46 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -129,7 +130,7 @@ */ @AnnotatedFor({"nullness"}) @SuppressWarnings("unchecked") -public class PriorityBlockingQueue extends AbstractQueue +public @Modifiable class PriorityBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = 5595510919245408276L; @@ -727,7 +728,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable PriorityBlockingQueue this, Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable PriorityBlockingQueue this, @Modifiable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -737,7 +738,7 @@ public int drainTo(@GuardSatisfied @Shrinkable PriorityBlockingQueue this, Co * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable PriorityBlockingQueue this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable PriorityBlockingQueue this, @Modifiable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 577c5a9d7ba5..ccc82b877159 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.NonNull; @@ -102,7 +103,7 @@ * @param the type of elements held in this queue */ @AnnotatedFor({"nullness"}) -public class SynchronousQueue extends AbstractQueue +public @Modifiable class SynchronousQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = -3223113410248163686L; @@ -1103,7 +1104,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable SynchronousQueue this, Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable SynchronousQueue this, @Modifiable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1119,7 +1120,7 @@ public int drainTo(@GuardSatisfied @Shrinkable SynchronousQueue this, Collect * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @Shrinkable SynchronousQueue this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable SynchronousQueue this, @Modifiable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); From eb00a46ae50bef7f1f241e5370fb758f376a3c64 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 29 Jan 2026 17:07:39 -0800 Subject: [PATCH 018/119] annotated IdentityHashMap, WeakHashMap, and ConcurrentHashMap --- .../classes/java/util/IdentityHashMap.java | 4 +-- .../share/classes/java/util/WeakHashMap.java | 3 ++- .../util/concurrent/ConcurrentHashMap.java | 26 ++++++++++--------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 4d75e1569f06..b249b8f1be58 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -166,7 +166,7 @@ @CFComment({"lock/nullness: This collection can only contain null values"}) @AnnotatedFor({"lock", "nullness", "index"}) -public class IdentityHashMap +public @Modifiable class IdentityHashMap extends AbstractMap implements Map, java.io.Serializable, Cloneable { @@ -1255,7 +1255,7 @@ public Spliterator spliterator() { private class EntrySet extends AbstractSet> { @SideEffectFree - public Iterator> iterator() { + public Iterator> iterator() { return new EntryIterator(); } @Pure diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 0bf358ec1f60..caf82fb03918 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -151,7 +152,7 @@ */ @CFComment({"lock: permits null keys and values"}) @AnnotatedFor({"lock", "index", "nullness"}) -public class WeakHashMap +public @Modifiable class WeakHashMap extends AbstractMap implements Map { diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index f5bfb81b94a0..e5c0c0efc050 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -36,6 +36,8 @@ package java.util.concurrent; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -280,7 +282,7 @@ * @param the type of mapped values */ @AnnotatedFor({"nullness"}) -public class ConcurrentHashMap extends AbstractMap +public @Modifiable class ConcurrentHashMap extends AbstractMap implements ConcurrentMap, Serializable { private static final long serialVersionUID = 7249069246763182397L; @@ -1310,7 +1312,7 @@ public Collection values() { * @return the set view */ @SideEffectFree - public Set> entrySet() { + public Set> entrySet() { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); @@ -3549,7 +3551,7 @@ public final Map.Entry next(@NonEmpty EntryIterator this) { /** * Exported Entry for EntryIterator. */ - static final class MapEntry implements Map.Entry { + static final @Modifiable class MapEntry implements Map.Entry { final K key; // non-null V val; // non-null final ConcurrentHashMap map; @@ -4275,7 +4277,7 @@ public int reduceValuesToInt(long parallelismThreshold, * @since 1.8 */ public void forEachEntry(long parallelismThreshold, - Consumer> action) { + Consumer> action) { if (action == null) throw new NullPointerException(); new ForEachEntryTask(null, batchFor(parallelismThreshold), 0, 0, table, action).invoke(); @@ -4295,7 +4297,7 @@ public void forEachEntry(long parallelismThreshold, * @since 1.8 */ public void forEachEntry(long parallelismThreshold, - Function, ? extends U> transformer, + Function, ? extends U> transformer, Consumer action) { if (transformer == null || action == null) throw new NullPointerException(); @@ -4321,7 +4323,7 @@ public void forEachEntry(long parallelismThreshold, * @since 1.8 */ public U searchEntries(long parallelismThreshold, - Function, ? extends U> searchFunction) { + Function, ? extends U> searchFunction) { if (searchFunction == null) throw new NullPointerException(); return new SearchEntriesTask (null, batchFor(parallelismThreshold), 0, 0, table, @@ -4339,7 +4341,7 @@ public U searchEntries(long parallelismThreshold, * @since 1.8 */ public Map.Entry reduceEntries(long parallelismThreshold, - BiFunction, Map.Entry, ? extends Map.Entry> reducer) { + BiFunction, ? super Map.@Unmodifiable Entry, ? extends Map.Entry> reducer) { if (reducer == null) throw new NullPointerException(); return new ReduceEntriesTask (null, batchFor(parallelismThreshold), 0, 0, table, @@ -4363,7 +4365,7 @@ public Map.Entry reduceEntries(long parallelismThreshold, * @since 1.8 */ public U reduceEntries(long parallelismThreshold, - Function, ? extends U> transformer, + Function, ? extends U> transformer, BiFunction reducer) { if (transformer == null || reducer == null) throw new NullPointerException(); @@ -4388,7 +4390,7 @@ public U reduceEntries(long parallelismThreshold, * @since 1.8 */ public double reduceEntriesToDouble(long parallelismThreshold, - ToDoubleFunction> transformer, + ToDoubleFunction> transformer, double basis, DoubleBinaryOperator reducer) { if (transformer == null || reducer == null) @@ -4414,7 +4416,7 @@ public double reduceEntriesToDouble(long parallelismThreshold, * @since 1.8 */ public long reduceEntriesToLong(long parallelismThreshold, - ToLongFunction> transformer, + ToLongFunction> transformer, long basis, LongBinaryOperator reducer) { if (transformer == null || reducer == null) @@ -4440,7 +4442,7 @@ public long reduceEntriesToLong(long parallelismThreshold, * @since 1.8 */ public int reduceEntriesToInt(long parallelismThreshold, - ToIntFunction> transformer, + ToIntFunction> transformer, int basis, IntBinaryOperator reducer) { if (transformer == null || reducer == null) @@ -4849,7 +4851,7 @@ public void forEach(Consumer action) { * entries. This class cannot be directly instantiated. See * {@link #entrySet()}. */ - static final class EntrySetView extends CollectionView> + static final @Modifiable class EntrySetView extends CollectionView> implements Set>, java.io.Serializable { private static final long serialVersionUID = 2249069246763182397L; EntrySetView(ConcurrentHashMap map) { super(map); } From 720e98f99892be912bfa4dd9d80cdadda7484da4 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 1 Feb 2026 19:19:33 -0800 Subject: [PATCH 019/119] finished annotating concurrentSkipListMap and concurrentSkipListSet --- .../concurrent/ConcurrentSkipListMap.java | 25 +++++++++++-------- .../concurrent/ConcurrentSkipListSet.java | 25 +++++++++++-------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index bda48d782303..03696ecca13f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -36,6 +36,9 @@ package java.util.concurrent; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; @@ -122,7 +125,7 @@ * @param the type of mapped values * @since 1.6 */ -public class ConcurrentSkipListMap extends AbstractMap +public @Modifiable class ConcurrentSkipListMap extends AbstractMap implements ConcurrentNavigableMap, Cloneable, Serializable { /* * This class implements a tree-like two-dimensionally linked skip @@ -1695,7 +1698,7 @@ public Collection values() { * sorted in ascending key order */ @SideEffectFree - public Set> entrySet() { + public Set> entrySet() { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1903,6 +1906,7 @@ public K lastKey(@NonEmpty ConcurrentSkipListMap this) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -1915,6 +1919,7 @@ public V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -2004,7 +2009,7 @@ public ConcurrentNavigableMap tailMap(K fromKey) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ - public Map.Entry lowerEntry(K key) { + public Map.@Unmodifiable Entry lowerEntry(K key) { return findNearEntry(key, LT, comparator); } @@ -2027,7 +2032,7 @@ public K lowerKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ - public Map.Entry floorEntry(K key) { + public Map.@Unmodifiable Entry floorEntry(K key) { return findNearEntry(key, LT|EQ, comparator); } @@ -2050,7 +2055,7 @@ public K floorKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ - public Map.Entry ceilingEntry(K key) { + public Map.@Unmodifiable Entry ceilingEntry(K key) { return findNearEntry(key, GT|EQ, comparator); } @@ -2073,7 +2078,7 @@ public K ceilingKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ - public Map.Entry higherEntry(K key) { + public Map.@Unmodifiable Entry higherEntry(K key) { return findNearEntry(key, GT, comparator); } @@ -2093,7 +2098,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ - public Map.Entry firstEntry() { + public Map.@Unmodifiable Entry firstEntry() { return findFirstEntry(); } @@ -2103,7 +2108,7 @@ public Map.Entry firstEntry() { * The returned entry does not support * the {@code Entry.setValue} method. */ - public Map.Entry lastEntry() { + public Map.@Unmodifiable Entry lastEntry() { return findLastEntry(); } @@ -2113,7 +2118,7 @@ public Map.Entry lastEntry() { * The returned entry does not support * the {@code Entry.setValue} method. */ - public Map.Entry pollFirstEntry() { + public Map.@Unmodifiable Entry pollFirstEntry() { return doRemoveFirstEntry(); } @@ -2123,7 +2128,7 @@ public Map.Entry pollFirstEntry() { * The returned entry does not support * the {@code Entry.setValue} method. */ - public Map.Entry pollLastEntry() { + public Map.@Unmodifiable Entry pollLastEntry() { return doRemoveLastEntry(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 1e02531ced65..564ce540b275 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -37,6 +37,9 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -107,7 +110,7 @@ * @since 1.6 */ @AnnotatedFor({"nullness"}) -public class ConcurrentSkipListSet +public @Modifiable class ConcurrentSkipListSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { @@ -296,7 +299,7 @@ public void clear() { * @return an iterator over the elements in this set in ascending order */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { return m.navigableKeySet().iterator(); } @@ -305,7 +308,7 @@ public void clear() { * * @return an iterator over the elements in this set in descending order */ - public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { return m.descendingKeySet().iterator(); } @@ -437,6 +440,7 @@ public E last(@NonEmpty ConcurrentSkipListSet this) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -449,6 +453,7 @@ public void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ + @WillThrowUOE public void addLast(E e) { throw new UnsupportedOperationException(); } @@ -459,7 +464,7 @@ public void addLast(E e) { * {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { @@ -473,7 +478,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement, boolean inclusive) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement, boolean inclusive) { return new ConcurrentSkipListSet(m.headMap(toElement, inclusive)); } @@ -482,7 +487,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code fromElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean inclusive) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean inclusive) { return new ConcurrentSkipListSet(m.tailMap(fromElement, inclusive)); } @@ -492,7 +497,7 @@ public void addLast(E e) { * {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, E toElement) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } @@ -501,7 +506,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement) { return headSet(toElement, false); } @@ -510,7 +515,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code fromElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement) { return tailSet(fromElement, true); } @@ -526,7 +531,7 @@ public void addLast(E e) { * * @return a reverse order view of this set */ - public @PolyGrowShrink @PolyNonEmpty NavigableSet descendingSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet descendingSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { return new ConcurrentSkipListSet(m.descendingMap()); } From d06826e62f4230af55a22640ff1b4b56a2510fca Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 5 Feb 2026 13:36:11 -0800 Subject: [PATCH 020/119] finished annotating iterators. --- src/java.base/share/classes/java/lang/Iterable.java | 3 ++- src/java.base/share/classes/java/util/ListIterator.java | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Iterable.java b/src/java.base/share/classes/java/lang/Iterable.java index 2b0cacbbfbc6..72ae4ad6bc07 100644 --- a/src/java.base/share/classes/java/lang/Iterable.java +++ b/src/java.base/share/classes/java/lang/Iterable.java @@ -25,6 +25,7 @@ package java.lang; import org.checkerframework.checker.index.qual.PolyGrowShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.common.aliasing.qual.NonLeaked; import org.checkerframework.framework.qual.AnnotatedFor; @@ -51,7 +52,7 @@ public interface Iterable { * * @return an Iterator. */ - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Iterable this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterable this); /** * Performs the given action for each element of the {@code Iterable} diff --git a/src/java.base/share/classes/java/util/ListIterator.java b/src/java.base/share/classes/java/util/ListIterator.java index b44e644f1d3a..ae50030ca9ce 100644 --- a/src/java.base/share/classes/java/util/ListIterator.java +++ b/src/java.base/share/classes/java/util/ListIterator.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.GTENegativeOne; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -166,7 +167,7 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ - void remove(@GuardSatisfied ListIterator this); + void remove(@Modifiable @GuardSatisfied ListIterator this); /** * Replaces the last element returned by {@link #next} or @@ -188,7 +189,7 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ - void set(@GuardSatisfied ListIterator this, E e); + void set(@Modifiable @GuardSatisfied ListIterator this, E e); /** * Inserts the specified element into the list (optional operation). @@ -210,5 +211,5 @@ public interface ListIterator extends Iterator { * @throws IllegalArgumentException if some aspect of this element * prevents it from being added to this list */ - void add(@GuardSatisfied ListIterator this, E e); + void add(@Modifiable @GuardSatisfied ListIterator this, E e); } From 65dc3cb5cb37529cac8780fb1f969d75c0c4ad24 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 9 Feb 2026 17:36:41 -0800 Subject: [PATCH 021/119] changed hashSet and TreeSet to growShrink to pass all-system test --- .../share/classes/java/util/HashSet.java | 15 +++++++-------- .../share/classes/java/util/TreeSet.java | 14 +++++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 90f1c0ac9a4f..018be7ccf6fe 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -28,9 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.GrowShrink; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -106,7 +105,7 @@ */ @AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class HashSet +public @GrowShrink class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { @@ -122,7 +121,7 @@ * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @Modifiable HashSet() { + public @GrowShrink HashSet() { map = new HashMap<>(); } @@ -135,7 +134,7 @@ * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @GrowShrink @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -153,7 +152,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @GrowShrink HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -169,7 +168,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable HashSet(@NonNegative int initialCapacity) { + public @GrowShrink HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -186,7 +185,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @Modifiable HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @GrowShrink HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 4a8662e1fc35..d85b376976ab 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.GrowShrink; import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -112,13 +112,13 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public @Modifiable class TreeSet extends AbstractSet +public @GrowShrink class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { /** * The backing map. */ - private transient @Modifiable NavigableMap m; + private transient @GrowShrink NavigableMap m; // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); @@ -143,7 +143,7 @@ * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable TreeSet() { + public @GrowShrink TreeSet() { this(new TreeMap<>()); } @@ -160,7 +160,7 @@ * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable TreeSet(@Nullable Comparator comparator) { + public @GrowShrink TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -178,7 +178,7 @@ * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @GrowShrink @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -190,7 +190,7 @@ * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @GrowShrink @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } From 4bd5c4ff80e1cb446d44bc5da091ac91e3387cb1 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 9 Feb 2026 19:15:55 -0800 Subject: [PATCH 022/119] fixed annotation in AbstractCollection due to merge conflict. --- .../share/classes/java/util/AbstractCollection.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index be73f3fa6d89..bc49adad9eaf 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -394,7 +394,7 @@ public boolean addAll(@Modifiable @GuardSatisfied AbstractCollection this, Co * @see #remove(Object) * @see #contains(Object) */ - public boolean removeAll(@GuardSatisfied @Shrinkable AbstractCollection this, Collection c) { + public boolean removeAll(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -429,7 +429,7 @@ public boolean removeAll(@GuardSatisfied @Shrinkable AbstractCollection this, * @see #remove(Object) * @see #contains(Object) */ - public boolean retainAll(@GuardSatisfied @Shrinkable AbstractCollection this, Collection c) { + public boolean retainAll(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -458,7 +458,7 @@ public boolean retainAll(@GuardSatisfied @Shrinkable AbstractCollection this, * * @throws UnsupportedOperationException {@inheritDoc} */ - public void clear(@GuardSatisfied @Shrinkable AbstractCollection this) { + public void clear(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { it.next(); From ff6662bbb803386eaf6b7c4ccf22d4b6896fee91 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 11 Feb 2026 16:48:02 -0800 Subject: [PATCH 023/119] minor changes so that the new type system can pass all-system test --- src/java.base/share/classes/java/util/Collection.java | 3 ++- src/java.base/share/classes/java/util/Queue.java | 4 ++-- .../share/classes/java/util/concurrent/BlockingQueue.java | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 612a0f5cb0f5..8d76a2d1465b 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -660,7 +661,7 @@ default boolean removeIf(@Modifiable @CanShrink Collection this, Predicate this); + void clear(@Shrinkable @GuardSatisfied @CanShrink Collection this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index 26ed1bf6ce50..cc485f39ea81 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.GrowShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -148,7 +148,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public @Modifiable interface Queue extends Collection { +public @GrowShrink interface Queue extends Collection { /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index c136c28ef52c..1ffcea7dba68 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -362,7 +362,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ - int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, @Modifiable Collection c); + int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, @Growable Collection c); /** * Removes at most the given number of available elements from @@ -387,5 +387,5 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ - int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, @Modifiable Collection c, int maxElements); + int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, @Growable Collection c, int maxElements); } From 20a219eded4b262258a89e79a8f57dfa1b1472ce Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 11 Feb 2026 23:04:28 -0800 Subject: [PATCH 024/119] finished revising list annotations --- .../classes/java/util/AbstractCollection.java | 16 +++++---- .../share/classes/java/util/AbstractList.java | 18 +++++----- .../java/util/AbstractSequentialList.java | 10 +++--- .../share/classes/java/util/Collection.java | 14 ++++---- .../share/classes/java/util/List.java | 36 ++++++++++--------- .../java/util/SequencedCollection.java | 12 ++++--- .../util/concurrent/CopyOnWriteArrayList.java | 10 +++--- 7 files changed, 63 insertions(+), 53 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index bc49adad9eaf..a91bb5e4ad57 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -31,8 +31,10 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -280,7 +282,7 @@ private static T[] finishToArray(T[] r, Iterator it) { * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ - public boolean add(@Modifiable @GuardSatisfied AbstractCollection this, E e) { + public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); } @@ -301,7 +303,7 @@ public boolean add(@Modifiable @GuardSatisfied AbstractCollection this, E e) * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public boolean remove(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) { @@ -364,7 +366,7 @@ public boolean containsAll(@UnknownModifiability @GuardSatisfied AbstractCollect * * @see #add(Object) */ - public boolean addAll(@Modifiable @GuardSatisfied AbstractCollection this, Collection c) { + public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Collection c) { boolean modified = false; for (E e : c) if (add(e)) @@ -394,7 +396,7 @@ public boolean addAll(@Modifiable @GuardSatisfied AbstractCollection this, Co * @see #remove(Object) * @see #contains(Object) */ - public boolean removeAll(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -429,7 +431,7 @@ public boolean removeAll(@Modifiable @GuardSatisfied @CanShrink AbstractCollecti * @see #remove(Object) * @see #contains(Object) */ - public boolean retainAll(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -458,7 +460,7 @@ public boolean retainAll(@Modifiable @GuardSatisfied @CanShrink AbstractCollecti * * @throws UnsupportedOperationException {@inheritDoc} */ - public void clear(@Modifiable @GuardSatisfied @CanShrink AbstractCollection this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { it.next(); diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index f5028447a472..2dea3eee4646 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -31,7 +31,9 @@ import org.checkerframework.checker.index.qual.IndexOrHigh; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -135,7 +137,7 @@ protected AbstractList() { * prevents it from being added to this list */ @EnsuresNonEmpty("this") - public boolean add(@Modifiable @GuardSatisfied AbstractList this, E e) { + public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { add(size(), e); return true; } @@ -161,7 +163,7 @@ public boolean add(@Modifiable @GuardSatisfied AbstractList this, E e) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(@Modifiable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { + public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -178,7 +180,7 @@ public E set(@Modifiable @GuardSatisfied AbstractList this, @IndexFor({"this" * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(@Modifiable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { + public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -192,7 +194,7 @@ public void add(@Modifiable @GuardSatisfied AbstractList this, @IndexOrHigh({ * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@Modifiable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); } @@ -270,7 +272,7 @@ public E remove(@Modifiable @GuardSatisfied @CanShrink AbstractList this, @In * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ - public void clear(@Modifiable @GuardSatisfied @CanShrink AbstractList this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { removeRange(0, size()); } @@ -294,7 +296,7 @@ public void clear(@Modifiable @GuardSatisfied @CanShrink AbstractList this) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public boolean addAll(@Modifiable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { + public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { @@ -629,7 +631,7 @@ public int hashCode(@UnknownModifiability @GuardSatisfied AbstractList this) * @param fromIndex index of first element to be removed * @param toIndex index after last element to be removed */ - protected void removeRange(@Modifiable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + protected void removeRange(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i thi * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(@Modifiable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public E set(@Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { ListIterator e = listIterator(index); E oldVal = e.next(); @@ -158,7 +158,7 @@ public E set(@Modifiable @GuardSatisfied AbstractSequentialList this, int ind * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(@Modifiable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public void add(@Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { listIterator(index).add(element); } catch (NoSuchElementException exc) { @@ -183,7 +183,7 @@ public void add(@Modifiable @GuardSatisfied AbstractSequentialList this, int * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@Modifiable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { try { ListIterator e = listIterator(index); E outCast = e.next(); @@ -226,7 +226,7 @@ public E remove(@Modifiable @GuardSatisfied @CanShrink AbstractSequentialList * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public boolean addAll(@Modifiable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { + public boolean addAll(@Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { try { boolean modified = false; ListIterator e1 = listIterator(index); diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 8d76a2d1465b..81e1951c2ad7 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -32,8 +32,8 @@ import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -494,7 +494,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, E e); + boolean add(@Growable @GuardSatisfied Collection this, E e); /** * Removes a single instance of the specified element from this @@ -516,7 +516,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, @UnknownSignedness Object o); + boolean remove(@Shrinkable @GuardSatisfied @CanShrink Collection this, @UnknownSignedness Object o); // Bulk Operations @@ -568,7 +568,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Collection c); + boolean addAll(@Growable @GuardSatisfied Collection this, Collection c); /** * Removes all of this collection's elements that are also contained in the @@ -593,7 +593,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Collection c); + boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink Collection this, Collection c); /** * Removes all of the elements of this collection that satisfy the given @@ -617,7 +617,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Predicate filter) { + default boolean removeIf(@Shrinkable @CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); @@ -652,7 +652,7 @@ default boolean removeIf(@Modifiable @CanShrink Collection this, Predicate this, Collection c); + boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Collection this, Collection c); /** * Removes all of the elements from this collection (optional operation). diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 41b343ae6af9..7ffed30a226c 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -35,9 +35,11 @@ import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -305,7 +307,7 @@ public interface List extends SequencedCollection { @ReleasesNoLocks @SideEffectsOnly("this") @EnsuresNonEmpty("this") - boolean add(@Modifiable @GuardSatisfied List this, E e); + boolean add(@Growable @GuardSatisfied List this, E e); /** * Removes the first occurrence of the specified element from this list, @@ -329,7 +331,7 @@ public interface List extends SequencedCollection { * is not supported by this list */ @SideEffectsOnly("this") - boolean remove(@Modifiable @GuardSatisfied @CanShrink List this, @UnknownSignedness Object o); + boolean remove(@Shrinkable @GuardSatisfied @CanShrink List this, @UnknownSignedness Object o); // Bulk Modification Operations @@ -378,7 +380,7 @@ public interface List extends SequencedCollection { */ @SideEffectsOnly("this") @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@Modifiable @GuardSatisfied List this, Collection c); + boolean addAll(@Growable @GuardSatisfied List this, Collection c); /** * Inserts all of the elements in the specified collection into this @@ -409,7 +411,7 @@ public interface List extends SequencedCollection { */ @SideEffectsOnly("this") @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@Modifiable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); + boolean addAll(@Growable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); /** * Removes from this list all of its elements that are contained in the @@ -429,7 +431,7 @@ public interface List extends SequencedCollection { * @see #remove(Object) * @see #contains(Object) */ - boolean removeAll(@Modifiable @GuardSatisfied @CanShrink List this, Collection c); + boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink List this, Collection c); /** * Retains only the elements in this list that are contained in the @@ -451,7 +453,7 @@ public interface List extends SequencedCollection { * @see #remove(Object) * @see #contains(Object) */ - boolean retainAll(@Modifiable @GuardSatisfied @CanShrink List this, Collection c); + boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink List this, Collection c); /** * Replaces each element of this list with the result of applying the @@ -482,7 +484,7 @@ public interface List extends SequencedCollection { * (optional) * @since 1.8 */ - default void replaceAll(@Modifiable List this, UnaryOperator operator) { + default void replaceAll(@Replaceable List this, UnaryOperator operator) { Objects.requireNonNull(operator); final ListIterator li = this.listIterator(); while (li.hasNext()) { @@ -550,7 +552,7 @@ default void replaceAll(@Modifiable List this, UnaryOperator operator) { * @since 1.8 */ @SuppressWarnings({"unchecked", "rawtypes"}) - default void sort(@Modifiable List this, Comparator c) { + default void sort(@Replaceable List this, Comparator c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator i = this.listIterator(); @@ -567,7 +569,7 @@ default void sort(@Modifiable List this, Comparator c) { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ - void clear(@Modifiable @GuardSatisfied @CanShrink List this); + void clear(@Shrinkable @GuardSatisfied @CanShrink List this); // Comparison and hashing @@ -641,7 +643,7 @@ default void sort(@Modifiable List this, Comparator c) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ - E set(@Modifiable @GuardSatisfied List this, @IndexFor({"this"}) int index, E element); + E set(@Replaceable @GuardSatisfied List this, @IndexFor({"this"}) int index, E element); /** * Inserts the specified element at the specified position in this list @@ -664,7 +666,7 @@ default void sort(@Modifiable List this, Comparator c) { */ @ReleasesNoLocks @SideEffectsOnly("this") - void add(@Modifiable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, E element); + void add(@Growable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, E element); /** * Removes the element at the specified position in this list (optional @@ -680,7 +682,7 @@ default void sort(@Modifiable List this, Comparator c) { * ({@code index < 0 || index >= size()}) */ @ReleasesNoLocks - E remove(@Modifiable @GuardSatisfied @CanShrink List this, @IndexFor({"this"}) int index); + E remove(@Shrinkable @GuardSatisfied @CanShrink List this, @IndexFor({"this"}) int index); // Search Operations @@ -848,7 +850,7 @@ default Spliterator spliterator() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default void addFirst(@Modifiable List this, E e) { + default void addFirst(@Growable List this, E e) { this.add(0, e); } @@ -862,7 +864,7 @@ default void addFirst(@Modifiable List this, E e) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default void addLast(@Modifiable List this, E e) { + default void addLast(@Growable List this, E e) { this.add(e); } @@ -913,7 +915,7 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeFirst(@Modifiable List this) { + default E removeFirst(@Shrinkable List this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { @@ -932,7 +934,7 @@ default E removeFirst(@Modifiable List this) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeLast(@Modifiable List this) { + default E removeLast(@Shrinkable List this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 0eae7eab4cc0..af1567e64e52 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -26,7 +26,9 @@ package java.util; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; + /** * A collection that has a well-defined encounter order, that supports operations at both ends, @@ -106,7 +108,7 @@ public interface SequencedCollection extends Collection { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default void addFirst(@Modifiable SequencedCollection this, E e) { + default void addFirst(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -124,7 +126,7 @@ default void addFirst(@Modifiable SequencedCollection this, E e) { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default void addLast(@Modifiable SequencedCollection this, E e) { + default void addLast(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -175,7 +177,7 @@ default E getLast() { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default E removeFirst(@Modifiable SequencedCollection this) { + default E removeFirst(@Shrinkable SequencedCollection this) { var it = this.iterator(); E e = it.next(); it.remove(); @@ -197,7 +199,7 @@ default E removeFirst(@Modifiable SequencedCollection this) { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ - default E removeLast(@Modifiable SequencedCollection this) { + default E removeLast(@Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); E e = it.next(); it.remove(); 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 c1e3a26613db..675648288395 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -37,6 +37,8 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -113,7 +115,7 @@ * @author Doug Lea * @param the type of elements held in this list */ -public class CopyOnWriteArrayList +public @Modifiable class CopyOnWriteArrayList implements List, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8673264195747942595L; @@ -1130,7 +1132,7 @@ public int hashCode() { * * @return an iterator over the elements in this list in proper sequence */ - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArrayList this) { + public @Unmodifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArrayList this) { return new COWIterator(getArray(), 0); } @@ -1142,7 +1144,7 @@ public int hashCode() { * traversing the iterator. The iterator does NOT support the * {@code remove}, {@code set} or {@code add} methods. */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArrayList this) { + public @Unmodifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArrayList this) { return new COWIterator(getArray(), 0); } @@ -1156,7 +1158,7 @@ public int hashCode() { * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink CopyOnWriteArrayList this, int index) { + public @Unmodifiable @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink CopyOnWriteArrayList this, int index) { Object[] es = getArray(); int len = es.length; if (index < 0 || index > len) From e7847033dac3c09ee775961f5250aadf128a1950 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 11 Feb 2026 23:38:33 -0800 Subject: [PATCH 025/119] changed the annotation on set --- .../share/classes/java/util/AbstractSet.java | 4 ++-- .../share/classes/java/util/NavigableSet.java | 6 +++--- src/java.base/share/classes/java/util/Set.java | 16 ++++++++-------- .../share/classes/java/util/SortedSet.java | 6 +++--- .../java/util/concurrent/ConcurrentHashMap.java | 2 +- .../util/concurrent/CopyOnWriteArraySet.java | 6 ++++-- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index 19e86415cd2d..777d0f98684e 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; @@ -176,7 +176,7 @@ public int hashCode(@UnknownModifiability @GuardSatisfied AbstractSet this) { * @see #remove(Object) * @see #contains(Object) */ - public boolean removeAll(@Modifiable @GuardSatisfied AbstractSet this, Collection c) { + public boolean removeAll(@Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 705644210f64..300a891ff253 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; @@ -351,7 +351,7 @@ public interface NavigableSet extends SortedSet { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeFirst(@Modifiable NavigableSet this) { + default E removeFirst(@Shrinkable NavigableSet this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { @@ -370,7 +370,7 @@ default E removeFirst(@Modifiable NavigableSet this) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeLast(@Modifiable NavigableSet this) { + default E removeLast(@Shrinkable NavigableSet this) { if (this.isEmpty()) { throw new NoSuchElementException(); } else { diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 1de6dfba93ad..31a2db1c96a7 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -29,9 +29,9 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -284,7 +284,7 @@ public interface Set extends Collection { * prevents it from being added to this set */ @EnsuresNonEmpty("this") - boolean add(@Modifiable @GuardSatisfied Set this, E e); + boolean add(@Growable @GuardSatisfied Set this, E e); /** @@ -308,7 +308,7 @@ public interface Set extends Collection { * @throws UnsupportedOperationException if the {@code remove} operation * is not supported by this set */ - boolean remove(@Modifiable @GuardSatisfied Set this, @UnknownSignedness Object o); + boolean remove(@Shrinkable @GuardSatisfied Set this, @UnknownSignedness Object o); // Bulk Operations @@ -358,7 +358,7 @@ public interface Set extends Collection { * @see #add(Object) */ @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@Modifiable @GuardSatisfied Set this, Collection c); + boolean addAll(@Growable @GuardSatisfied Set this, Collection c); /** * Retains only the elements in this set that are contained in the @@ -381,7 +381,7 @@ public interface Set extends Collection { * or if the specified collection is null * @see #remove(Object) */ - boolean retainAll(@Modifiable @GuardSatisfied Set this, Collection c); + boolean retainAll(@Shrinkable @GuardSatisfied Set this, Collection c); /** * Removes from this set all of its elements that are contained in the @@ -404,7 +404,7 @@ public interface Set extends Collection { * @see #remove(Object) * @see #contains(Object) */ - boolean removeAll(@Modifiable @GuardSatisfied Set this, Collection c); + boolean removeAll(@Shrinkable @GuardSatisfied Set this, Collection c); /** * Removes all of the elements from this set (optional operation). @@ -413,7 +413,7 @@ public interface Set extends Collection { * @throws UnsupportedOperationException if the {@code clear} method * is not supported by this set */ - void clear(@Modifiable @GuardSatisfied Set this); + void clear(@Shrinkable @GuardSatisfied Set this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 375793aece47..94535ec80811 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.WillThrowUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; @@ -352,7 +352,7 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeFirst(@Modifiable SortedSet this) { + default E removeFirst(@Shrinkable SortedSet this) { E e = this.first(); this.remove(e); return e; @@ -370,7 +370,7 @@ default E removeFirst(@Modifiable SortedSet this) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ - default E removeLast(@Modifiable SortedSet this) { + default E removeLast(@Shrinkable SortedSet this) { E e = this.last(); this.remove(e); return e; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index e5c0c0efc050..b7c667428d5a 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4643,7 +4643,7 @@ public final boolean retainAll(Collection extends CollectionView + public static final @Modifiable class KeySetView extends CollectionView implements Set, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; @SuppressWarnings("serial") // Conditionally serializable 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 b0078296d26e..1a9ff75c0c03 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -37,6 +37,8 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -110,7 +112,7 @@ * @author Doug Lea * @param the type of elements held in this set */ -public class CopyOnWriteArraySet extends AbstractSet +public @Modifiable class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable { private static final long serialVersionUID = 5457747651344034263L; @@ -407,7 +409,7 @@ public boolean retainAll(Collection iterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArraySet this) { + public @Unmodifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArraySet this) { return al.iterator(); } From 64bf3127d5bbee1f0433ab3360f0d844a37e214b Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 12 Feb 2026 12:08:45 -0800 Subject: [PATCH 026/119] finished annotating queue --- src/java.base/share/classes/java/util/Deque.java | 14 ++++++-------- .../java/util/concurrent/ArrayBlockingQueue.java | 5 +++-- .../java/util/concurrent/BlockingQueue.java | 1 + .../util/concurrent/ConcurrentLinkedDeque.java | 3 ++- .../classes/java/util/concurrent/DelayQueue.java | 5 +++-- .../java/util/concurrent/LinkedBlockingDeque.java | 5 +++-- .../java/util/concurrent/LinkedBlockingQueue.java | 5 +++-- .../java/util/concurrent/LinkedTransferQueue.java | 5 +++-- .../util/concurrent/PriorityBlockingQueue.java | 5 +++-- .../java/util/concurrent/SynchronousQueue.java | 5 +++-- 10 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 445f32a4edb8..e2e8f3ed88d4 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -40,8 +40,6 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -240,7 +238,7 @@ * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - void addFirst(@Modifiable @GuardSatisfied Deque this, E e); + void addFirst(@GuardSatisfied Deque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -262,7 +260,7 @@ * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - void addLast(@Modifiable @GuardSatisfied Deque this, E e); + void addLast(@GuardSatisfied Deque this, E e); /** * Inserts the specified element at the front of this deque unless it would @@ -308,7 +306,7 @@ * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ - E removeFirst(@Modifiable @GuardSatisfied @NonEmpty @CanShrink Deque this); + E removeFirst(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** * Retrieves and removes the last element of this deque. This method @@ -318,7 +316,7 @@ * @return the tail of this deque * @throws NoSuchElementException if this deque is empty */ - E removeLast(@Modifiable @GuardSatisfied @NonEmpty @CanShrink Deque this); + E removeLast(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** * Retrieves and removes the first element of this deque, @@ -326,7 +324,7 @@ * * @return the head of this deque, or {@code null} if this deque is empty */ - @Nullable E pollFirst(@Modifiable @GuardSatisfied @CanShrink Deque this); + @Nullable E pollFirst(@GuardSatisfied @CanShrink Deque this); /** * Retrieves and removes the last element of this deque, @@ -334,7 +332,7 @@ * * @return the tail of this deque, or {@code null} if this deque is empty */ - @Nullable E pollLast(@Modifiable @GuardSatisfied @CanShrink Deque this); + @Nullable E pollLast(@GuardSatisfied @CanShrink Deque this); /** * Retrieves, but does not remove, the first element of this deque. 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 0d40cfae57c2..31dca4513aea 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -718,7 +719,7 @@ private static void circularClear(Object[] items, int i, int end) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Modifiable Collection c) { + public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -728,7 +729,7 @@ public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Modif * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Modifiable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index 1ffcea7dba68..8561dc415bf0 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index b3a9cf89266e..9c390690cc60 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -112,7 +113,7 @@ * @param the type of elements held in this deque */ @AnnotatedFor({"nullness"}) -public class ConcurrentLinkedDeque +public @Modifiable class ConcurrentLinkedDeque extends AbstractCollection implements Deque, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 72db082227fe..09d38a174dfd 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,6 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -387,7 +388,7 @@ public int size() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Modifiable Collection c) { + public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -397,7 +398,7 @@ public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Modifiable Co * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Modifiable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); 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 0a6e918d9b3d..d640e732d39c 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -744,7 +745,7 @@ public int remainingCapacity() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Modifiable Collection c) { + public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -754,7 +755,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Modi * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Modifiable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); 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 95a3d643a3e3..82f002fa2f12 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -706,7 +707,7 @@ public void clear(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Modifiable Collection c) { + public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -716,7 +717,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Modi * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Modifiable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 7aed5196d7ae..88f512bfbaac 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -1325,7 +1326,7 @@ public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { + public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1339,7 +1340,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Colle * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); 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 e5d00dcf2cd3..63083ab15d7a 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -728,7 +729,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Modifiable Collection c) { + public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -738,7 +739,7 @@ public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Mo * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Modifiable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 7ddfa8ffdfd9..236aea0d1ffd 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -40,6 +40,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.NonNull; @@ -1104,7 +1105,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Modifiable Collection c) { + public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1120,7 +1121,7 @@ public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Modifia * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Modifiable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); From d53041a56d2e7d2ffbb94512f42b253ae36a2b76 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 12 Feb 2026 13:54:25 -0800 Subject: [PATCH 027/119] fixed annotations in Collections --- .../share/classes/java/util/Arrays.java | 4 +-- .../share/classes/java/util/Collections.java | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index f425b39811a2..b293cc708df7 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.SearchIndexFor; import org.checkerframework.checker.interning.qual.PolyInterned; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.mustcall.qual.MustCallUnknown; import org.checkerframework.checker.mustcall.qual.PolyMustCall; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -4274,7 +4274,7 @@ private static boolean[] copyOfRangeBoolean(boolean[] original, int from, int to @SafeVarargs @SideEffectFree @SuppressWarnings("varargs") - public static @Modifiable @PolyNonEmpty List asList(T @PolyNonEmpty... a) { + public static @Replaceable @PolyNonEmpty List asList(T @PolyNonEmpty... a) { return new ArrayList<>(a); } diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 8be1aa8d3d53..51de9366a528 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -31,8 +31,9 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -172,7 +173,7 @@ private Collections() { * @see List#sort(Comparator) */ @SuppressWarnings("unchecked") - public static > void sort(@Modifiable List list) { + public static > void sort(@Replaceable List list) { list.sort(null); } @@ -206,7 +207,7 @@ public static > void sort(@Modifiable List li * @see List#sort(Comparator) */ @SuppressWarnings({"unchecked", "rawtypes"}) - public static void sort(@Modifiable List list, @Nullable Comparator c) { + public static void sort(@Replaceable List list, @Nullable Comparator c) { list.sort(c); } @@ -412,7 +413,7 @@ else if (cmp > 0) * @see List#reversed List.reversed */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void reverse(@Modifiable @GuardSatisfied List list) { + public static void reverse(@Replaceable @GuardSatisfied List list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i list) { * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the {@code set} operation. */ - public static void shuffle(@Modifiable @GuardSatisfied List list) { + public static void shuffle(@Replaceable @GuardSatisfied List list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); // harmless race. @@ -482,7 +483,7 @@ public static void shuffle(@Modifiable @GuardSatisfied List list) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void shuffle(@Modifiable List list, Random rnd) { + public static void shuffle(@Replaceable List list, Random rnd) { shuffle(list, (RandomGenerator) rnd); } @@ -511,7 +512,7 @@ public static void shuffle(@Modifiable List list, Random rnd) { * @since 21 */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void shuffle(@Modifiable @GuardSatisfied List list, RandomGenerator rnd) { + public static void shuffle(@Replaceable @GuardSatisfied List list, RandomGenerator rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) @@ -549,7 +550,7 @@ public static void shuffle(@Modifiable @GuardSatisfied List list, RandomGener * @since 1.4 */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void swap(@Modifiable @GuardSatisfied List list, int i, int j) { + public static void swap(@Replaceable @GuardSatisfied List list, int i, int j) { // instead of using a raw type here, it's possible to capture // the wildcard but it will require a call to a supplementary // private method @@ -578,7 +579,7 @@ private static void swap(Object[] arr, int i, int j) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void fill(@Modifiable @GuardSatisfied List list, T obj) { + public static void fill(@Replaceable @GuardSatisfied List list, T obj) { int size = list.size(); if (size < FILL_THRESHOLD || list instanceof RandomAccess) { @@ -611,7 +612,7 @@ public static void fill(@Modifiable @GuardSatisfied List list, T * @throws UnsupportedOperationException if the destination list's * list-iterator does not support the {@code set} operation. */ - public static void copy(@Modifiable List dest, @UnknownModifiability List src) { + public static void copy(@Replaceable List dest, @UnknownModifiability List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -839,7 +840,7 @@ public static T max(@UnknownModifiability Collection coll, @Nul * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static void rotate(@Modifiable @GuardSatisfied List list, int distance) { + public static void rotate(@Replaceable @GuardSatisfied List list, int distance) { if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) rotate1(list, distance); else @@ -903,7 +904,7 @@ private static void rotate2(List list, int distance) { * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static boolean replaceAll(@Modifiable List list, @Nullable T oldVal, T newVal) { + public static boolean replaceAll(@Replaceable List list, @Nullable T oldVal, T newVal) { boolean result = false; int size = list.size(); if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { @@ -6109,7 +6110,7 @@ public static boolean disjoint(@UnknownModifiability Collection c1, @UnknownM * @since 1.5 */ @SafeVarargs - public static boolean addAll(@Modifiable @GuardSatisfied Collection c, T... elements) { + public static boolean addAll(@Growable @GuardSatisfied Collection c, T... elements) { boolean result = false; for (T element : elements) result |= c.add(element); From b407a53bc87693e0b1b3b312e08815a6e5334921 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 12 Feb 2026 16:12:53 -0800 Subject: [PATCH 028/119] finished fixing annotation for map besides keySet, entrySet, and values --- .../share/classes/java/util/AbstractMap.java | 10 ++++--- .../share/classes/java/util/EnumMap.java | 3 +- .../classes/java/util/LinkedHashMap.java | 10 +++---- .../share/classes/java/util/Map.java | 30 +++++++++++-------- .../share/classes/java/util/NavigableMap.java | 6 ++-- .../share/classes/java/util/SequencedMap.java | 11 +++---- .../share/classes/java/util/TreeMap.java | 8 ++--- .../java/util/concurrent/ConcurrentMap.java | 17 ++++++----- 8 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 23b7dfd584f9..c78567322d81 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -29,6 +29,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.GrowReplace; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -240,7 +242,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, K key, V value) { + public @Nullable V put(@GrowReplace @GuardSatisfied AbstractMap this, K key, V value) { throw new UnsupportedOperationException(); } @@ -266,7 +268,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); Entry correctEntry = null; if (key==null) { @@ -311,7 +313,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, Map m) { + public void putAll(@GrowReplace @GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); } @@ -328,7 +330,7 @@ public void putAll(@Modifiable @GuardSatisfied AbstractMap this, Map this) { + public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { entrySet().clear(); } diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 1d170eda8739..9921309d39a8 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; @@ -97,7 +98,7 @@ * @since 1.5 */ @AnnotatedFor({"nullness", "index"}) -public class EnumMap, V> extends AbstractMap +public @Modifiable class EnumMap, V> extends AbstractMap implements java.io.Serializable, Cloneable { /** diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 4029c71fe3f9..8a88fc64f64b 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -451,7 +451,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public @Modifiable LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { + public LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); accessOrder = false; } @@ -467,7 +467,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * @param initialCapacity the initial capacity * @throws IllegalArgumentException if the initial capacity is negative */ - public @Modifiable LinkedHashMap(@NonNegative int initialCapacity) { + public LinkedHashMap(@NonNegative int initialCapacity) { super(initialCapacity); accessOrder = false; } @@ -476,7 +476,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * Constructs an empty insertion-ordered {@code LinkedHashMap} instance * with the default initial capacity (16) and load factor (0.75). */ - public @Modifiable LinkedHashMap() { + public LinkedHashMap() { super(); accessOrder = false; } @@ -490,7 +490,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * @param m the map whose mappings are to be placed in this map * @throws NullPointerException if the specified map is null */ - public @Modifiable @PolyNonEmpty LinkedHashMap(@PolyNonEmpty Map m) { + public @PolyNonEmpty LinkedHashMap(@PolyNonEmpty Map m) { super(); accessOrder = false; putMapEntries(m, false); @@ -507,7 +507,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public @Modifiable LinkedHashMap(@NonNegative int initialCapacity, + public LinkedHashMap(@NonNegative int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 31543928decc..cb00587d024c 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -30,8 +30,12 @@ import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.GrowReplace; +import org.checkerframework.checker.modifiability.qual.ShrinkReplace; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -307,7 +311,7 @@ public interface Map { @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) @EnsuresNonEmpty("this") - @Nullable V put(@Modifiable @GuardSatisfied Map this, K key, V value); + @Nullable V put(@GrowReplace @GuardSatisfied Map this, K key, V value); /** * Removes the mapping for a key from this map if it is present @@ -338,7 +342,7 @@ public interface Map { * map does not permit null keys ({@linkplain Collection##optional-restrictions optional}) */ @CFComment("nullness: key is not @Nullable because this map might not permit null values") - @Nullable V remove(@Modifiable @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); + @Nullable V remove(@Shrinkable @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); // Bulk Operations @@ -364,7 +368,7 @@ public interface Map { * @throws IllegalArgumentException if some property of a key or value in * the specified map prevents it from being stored in this map */ - void putAll(@Modifiable @GuardSatisfied Map this, Map m); + void putAll(@GrowReplace @GuardSatisfied Map this, Map m); /** * Removes all of the mappings from this map (optional operation). @@ -373,7 +377,7 @@ public interface Map { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this map */ - void clear(@Modifiable @GuardSatisfied Map this); + void clear(@Shrinkable @GuardSatisfied Map this); // Views @@ -537,7 +541,7 @@ interface Entry { * required to, throw this exception if the entry has been * removed from the backing map. */ - V setValue(Map.@Modifiable @GuardSatisfied Entry this, V value); + V setValue(Map.@Replaceable @GuardSatisfied Entry this, V value); /** * Compares the specified object with this entry for equality. @@ -824,7 +828,7 @@ default void forEach(@NonLeaked BiConsumer action) { * removed during iteration * @since 1.8 */ - default void replaceAll(@Modifiable Map this, BiFunction function) { + default void replaceAll(@Replaceable Map this, BiFunction function) { Objects.requireNonNull(function); for (Map.Entry entry : entrySet()) { K k; @@ -891,7 +895,7 @@ default void replaceAll(@Modifiable Map this, BiFunction this, K key, V value) { + default @Nullable V putIfAbsent(@Growable Map this, K key, V value) { V v = get(key); if (v == null) { v = put(key, value); @@ -935,7 +939,7 @@ default void replaceAll(@Modifiable Map this, BiFunction this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + default boolean remove(@Shrinkable Map this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { @@ -985,7 +989,7 @@ default boolean remove(@Modifiable Map this, @GuardSatisfied @UnknownSigne * or value prevents it from being stored in this map * @since 1.8 */ - default boolean replace(@Modifiable Map this, K key, V oldValue, V newValue) { + default boolean replace(@Replaceable Map this, K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { @@ -1033,7 +1037,7 @@ default boolean replace(@Modifiable Map this, K key, V oldValue, V newValu * or value prevents it from being stored in this map * @since 1.8 */ - default @Nullable V replace(@Modifiable Map this, K key, V value) { + default @Nullable V replace(@Replaceable Map this, K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); @@ -1115,7 +1119,7 @@ default boolean replace(@Modifiable Map this, K key, V oldValue, V newValu * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ - default @PolyNull V computeIfAbsent(@Modifiable Map this, K key, + default @PolyNull V computeIfAbsent(@Growable Map this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V v; @@ -1192,7 +1196,7 @@ default boolean replace(@Modifiable Map this, K key, V oldValue, V newValu * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ - default @Nullable V computeIfPresent(@Modifiable Map this, K key, + default @Nullable V computeIfPresent(@ShrinkReplace Map this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 7835c8504be5..13a51e210e14 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,7 +36,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -253,7 +253,7 @@ public interface NavigableMap extends SortedMap { * @return the removed first entry of this map, * or {@code null} if this map is empty */ - Map.@Nullable Entry pollFirstEntry(@Modifiable @GuardSatisfied NavigableMap this); + Map.@Nullable Entry pollFirstEntry(@Shrinkable @GuardSatisfied NavigableMap this); /** * Removes and returns a key-value mapping associated with @@ -262,7 +262,7 @@ public interface NavigableMap extends SortedMap { * @return the removed last entry of this map, * or {@code null} if this map is empty */ - Map.@Nullable Entry pollLastEntry(@Modifiable @GuardSatisfied NavigableMap this); + Map.@Nullable Entry pollLastEntry(@Shrinkable @GuardSatisfied NavigableMap this); /** * Returns a reverse order view of the mappings contained in this map. diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 0711dffb79a6..6fa7527fd60d 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -27,7 +27,8 @@ import jdk.internal.util.NullableKeyValueHolder; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.GrowReplace; +import org.checkerframework.checker.modifiability.qual.Shrinkable; /** * A Map that has a well-defined encounter order, that supports operations at both ends, and @@ -186,7 +187,7 @@ default Map.Entry lastEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default Map.Entry pollFirstEntry(@Modifiable SequencedMap this) { + default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { var it = entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); @@ -211,7 +212,7 @@ default Map.Entry pollFirstEntry(@Modifiable SequencedMap this) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default Map.Entry pollLastEntry(@Modifiable SequencedMap this) { + default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { var it = reversed().entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); @@ -237,7 +238,7 @@ default Map.Entry pollLastEntry(@Modifiable SequencedMap this) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default V putFirst(@Modifiable SequencedMap this, K k, V v) { + default V putFirst(@GrowReplace SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -256,7 +257,7 @@ default V putFirst(@Modifiable SequencedMap this, K k, V v) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default V putLast(@Modifiable SequencedMap this, K k, V v) { + default V putLast(@GrowReplace SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 901afedb715f..e0db302cd8d4 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -178,7 +178,7 @@ * {@code put(Object key, Object value)} call will throw a * {@code ClassCastException}. */ - public @Modifiable TreeMap() { + public TreeMap() { comparator = null; } @@ -196,7 +196,7 @@ * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ - public @Modifiable TreeMap(@Nullable Comparator comparator) { + public TreeMap(@Nullable Comparator comparator) { this.comparator = comparator; } @@ -214,7 +214,7 @@ * or are not mutually comparable * @throws NullPointerException if the specified map is null */ - public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { + public @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { comparator = null; putAll(m); } @@ -228,7 +228,7 @@ * and whose comparator is to be used to sort this map * @throws NullPointerException if the specified map is null */ - public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { + public @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 32286c17da65..2677b4aedca4 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -37,6 +37,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.ShrinkReplace; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; import org.checkerframework.checker.nullness.qual.NonNull; @@ -167,7 +170,7 @@ default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumer this, K key, V value); + @Nullable V putIfAbsent(@Growable ConcurrentMap this, K key, V value); /** * Removes the entry for a key only if currently mapped to a given value. @@ -198,7 +201,7 @@ default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumeroptional) */ - boolean remove(@Modifiable ConcurrentMap this, @UnknownSignedness Object key, @UnknownSignedness Object value); + boolean remove(@Shrinkable ConcurrentMap this, @UnknownSignedness Object key, @UnknownSignedness Object value); /** * Replaces the entry for a key only if currently mapped to a given value. @@ -230,7 +233,7 @@ default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumer this, K key, V oldValue, V newValue); + boolean replace(@Replaceable ConcurrentMap this, K key, V oldValue, V newValue); /** * Replaces the entry for a key only if currently mapped to some value. @@ -262,7 +265,7 @@ default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumer this, K key, V value); + @Nullable V replace(@Replaceable ConcurrentMap this, K key, V value); /** * {@inheritDoc} @@ -295,7 +298,7 @@ default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumer this, BiFunction function) { + default void replaceAll(@Replaceable ConcurrentMap this, BiFunction function) { Objects.requireNonNull(function); forEach((k,v) -> { while (!replace(k, v, function.apply(k, v))) { @@ -335,7 +338,7 @@ default void replaceAll(@Modifiable ConcurrentMap this, BiFunction this, K key, + default @PolyNull V computeIfAbsent(@Growable ConcurrentMap this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V oldValue, newValue; @@ -377,7 +380,7 @@ default void replaceAll(@Modifiable ConcurrentMap this, BiFunction this, K key, + default @PolyNull V computeIfPresent(@ShrinkReplace ConcurrentMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); for (V oldValue; (oldValue = get(key)) != null; ) { From 73e35cbe41b12acd9c48a2d72588d4adab48a4c6 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 16 Feb 2026 19:01:27 -0800 Subject: [PATCH 029/119] changed all @WillThrowUOE to @ThrowsUOE to match the checker --- .../share/classes/java/util/AbstractCollection.java | 2 +- src/java.base/share/classes/java/util/SortedMap.java | 6 +++--- src/java.base/share/classes/java/util/SortedSet.java | 6 +++--- src/java.base/share/classes/java/util/TreeMap.java | 6 +++--- src/java.base/share/classes/java/util/TreeSet.java | 6 +++--- .../classes/java/util/concurrent/ConcurrentSkipListMap.java | 6 +++--- .../classes/java/util/concurrent/ConcurrentSkipListSet.java | 6 +++--- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index a91bb5e4ad57..59acf37dc335 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -36,7 +36,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index cd527454d7fb..1b468a3e4b77 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -316,7 +316,7 @@ public interface SortedMap extends SequencedMap { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE default V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -332,7 +332,7 @@ default V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE default V putLast(K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 94535ec80811..f185cbb43c26 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -27,7 +27,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; @@ -293,7 +293,7 @@ public Comparator getComparator() { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE default void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -309,7 +309,7 @@ default void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE default void addLast(E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index e0db302cd8d4..a96ecfff2bce 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -343,7 +343,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -356,7 +356,7 @@ public V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public V putLast(K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index d85b376976ab..7de89e07e5c1 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.GrowShrink; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -508,7 +508,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -521,7 +521,7 @@ public void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public void addLast(E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 03696ecca13f..0415aa110448 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -1906,7 +1906,7 @@ public K lastKey(@NonEmpty ConcurrentSkipListMap this) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -1919,7 +1919,7 @@ public V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public V putLast(K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 564ce540b275..8e81e599faf1 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.WillThrowUOE; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -440,7 +440,7 @@ public E last(@NonEmpty ConcurrentSkipListSet this) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -453,7 +453,7 @@ public void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ - @WillThrowUOE + @ThrowsUOE public void addLast(E e) { throw new UnsupportedOperationException(); } From 60053fad9940808899c98ffbae07ac7c524acbce Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 19 Feb 2026 13:26:15 -0800 Subject: [PATCH 030/119] annotated Deque and ProcessBuilder for case study --- src/java.base/share/classes/java/lang/ProcessBuilder.java | 5 +++-- src/java.base/share/classes/java/util/Deque.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/lang/ProcessBuilder.java b/src/java.base/share/classes/java/lang/ProcessBuilder.java index 8fbb26db26dd..5c9453402f29 100644 --- a/src/java.base/share/classes/java/lang/ProcessBuilder.java +++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java @@ -25,6 +25,7 @@ package java.lang; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.mustcall.qual.MustCall; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.tainting.qual.Untainted; @@ -199,7 +200,7 @@ public final class ProcessBuilder // Lazily and racy initialize when needed, racy is ok, any logger is ok private static System.Logger LOGGER; - private List command; + @Modifiable private List command; private File directory; private Map environment; private boolean redirectErrorStream; @@ -283,7 +284,7 @@ public ProcessBuilder command(@Untainted String... command) { * * @return this process builder's program and its arguments */ - public List<@Untainted String> command() { + public @Modifiable List<@Untainted String> command() { return command; } diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index e2e8f3ed88d4..b4dc431e93af 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -40,6 +40,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.GrowShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -219,7 +220,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable interface Deque extends Queue, SequencedCollection { +public @GrowShrink interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, From 08b94e1ee86f32afbf8ee1f064e457de01831b78 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 19 Feb 2026 16:33:10 -0800 Subject: [PATCH 031/119] edited the annotation to fit the 3 2-level hierarchy. --- .../share/classes/java/util/AbstractMap.java | 7 ++++--- .../share/classes/java/util/ArrayList.java | 6 ++++-- src/java.base/share/classes/java/util/Deque.java | 5 +++-- .../share/classes/java/util/HashSet.java | 15 ++++++++------- src/java.base/share/classes/java/util/Map.java | 8 +++----- src/java.base/share/classes/java/util/Queue.java | 5 +++-- .../share/classes/java/util/SequencedMap.java | 7 ++++--- .../share/classes/java/util/TreeSet.java | 15 ++++++++------- .../java/util/concurrent/ConcurrentMap.java | 4 ++-- 9 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index c78567322d81..02ba232f5fda 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -29,7 +29,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.GrowReplace; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Replaceale; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; @@ -242,7 +243,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, K key, V value) { + public @Nullable V put(@Growable @Replaceable @GuardSatisfied AbstractMap this, K key, V value) { throw new UnsupportedOperationException(); } @@ -313,7 +314,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, Map m) { + public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); } diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 750209d0f6d5..b6beb582e247 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -32,7 +32,9 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.BottomModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -133,7 +135,7 @@ */ @CFComment("lock/nullness: Permit null elements") @AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class ArrayList extends AbstractList +public @Growable @Shrinkable @Replaceable class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @java.io.Serial diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index b4dc431e93af..20bfea32aad5 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -40,7 +40,8 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.GrowShrink; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -220,7 +221,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) -public @GrowShrink interface Deque extends Queue, SequencedCollection { +public @Growabel @Shrinkable interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 018be7ccf6fe..3695d763c571 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -28,7 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.GrowShrink; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -105,7 +106,7 @@ */ @AnnotatedFor({"lock", "nullness", "index"}) -public @GrowShrink class HashSet +public @Growable @Shrinkable class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { @@ -121,7 +122,7 @@ * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @GrowShrink HashSet() { + public HashSet() { map = new HashMap<>(); } @@ -134,7 +135,7 @@ * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @GrowShrink @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -152,7 +153,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @GrowShrink HashSet(@NonNegative int initialCapacity, float loadFactor) { + public HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -168,7 +169,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @GrowShrink HashSet(@NonNegative int initialCapacity) { + public HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -185,7 +186,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @GrowShrink HashSet(int initialCapacity, float loadFactor, boolean dummy) { + HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index cb00587d024c..84f4e94c5127 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -33,8 +33,6 @@ import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.GrowReplace; -import org.checkerframework.checker.modifiability.qual.ShrinkReplace; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -311,7 +309,7 @@ public interface Map { @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) @EnsuresNonEmpty("this") - @Nullable V put(@GrowReplace @GuardSatisfied Map this, K key, V value); + @Nullable V put(@Growable @Replaceable @GuardSatisfied Map this, K key, V value); /** * Removes the mapping for a key from this map if it is present @@ -368,7 +366,7 @@ public interface Map { * @throws IllegalArgumentException if some property of a key or value in * the specified map prevents it from being stored in this map */ - void putAll(@GrowReplace @GuardSatisfied Map this, Map m); + void putAll(@Growable @Replaceable @GuardSatisfied Map this, Map m); /** * Removes all of the mappings from this map (optional operation). @@ -1196,7 +1194,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ - default @Nullable V computeIfPresent(@ShrinkReplace Map this, K key, + default @Nullable V computeIfPresent(@Shrinkable @Replaceable Map this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index cc485f39ea81..f0d6042647f0 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -37,7 +37,8 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.GrowShrink; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -148,7 +149,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public @GrowShrink interface Queue extends Collection { +public @Growable @Shrinkable interface Queue extends Collection { /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 6fa7527fd60d..939a7bd2dbab 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -27,7 +27,8 @@ import jdk.internal.util.NullableKeyValueHolder; -import org.checkerframework.checker.modifiability.qual.GrowReplace; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; /** @@ -238,7 +239,7 @@ default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default V putFirst(@GrowReplace SequencedMap this, K k, V v) { + default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -257,7 +258,7 @@ default V putFirst(@GrowReplace SequencedMap this, K k, V v) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ - default V putLast(@GrowReplace SequencedMap this, K k, V v) { + default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 7de89e07e5c1..997cf849f7aa 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -28,7 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.GrowShrink; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -112,13 +113,13 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public @GrowShrink class TreeSet extends AbstractSet +public @Growable @Shrinkable class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { /** * The backing map. */ - private transient @GrowShrink NavigableMap m; + private transient @Growable @Shrinkable NavigableMap m; // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); @@ -143,7 +144,7 @@ * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @GrowShrink TreeSet() { + public TreeSet() { this(new TreeMap<>()); } @@ -160,7 +161,7 @@ * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @GrowShrink TreeSet(@Nullable Comparator comparator) { + public TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -178,7 +179,7 @@ * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @GrowShrink @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -190,7 +191,7 @@ * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @GrowShrink @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 2677b4aedca4..82451837df80 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceable; -import org.checkerframework.checker.modifiability.qual.ShrinkReplace; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; import org.checkerframework.checker.nullness.qual.NonNull; @@ -380,7 +380,7 @@ default void replaceAll(@Replaceable ConcurrentMap this, BiFunction this, K key, + default @PolyNull V computeIfPresent(@Shrinkable @Replaceable ConcurrentMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); for (V oldValue; (oldValue = get(key)) != null; ) { From b374a18b772b36b7fdbc0c6fa37c6cdd23128d48 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 22 Feb 2026 20:33:33 -0800 Subject: [PATCH 032/119] finished annotating polyShrink --- .../share/classes/java/util/AbstractMap.java | 8 +++++--- src/java.base/share/classes/java/util/HashMap.java | 8 +++++--- .../share/classes/java/util/Hashtable.java | 8 +++++--- .../share/classes/java/util/IdentityHashMap.java | 8 +++++--- .../share/classes/java/util/LinkedHashMap.java | 14 ++++++++------ src/java.base/share/classes/java/util/Map.java | 7 ++++--- .../share/classes/java/util/NavigableMap.java | 5 +++-- .../share/classes/java/util/SequencedMap.java | 8 +++++--- .../share/classes/java/util/SortedMap.java | 7 ++++--- src/java.base/share/classes/java/util/TreeMap.java | 12 +++++++----- .../share/classes/java/util/WeakHashMap.java | 8 +++++--- .../java/util/concurrent/ConcurrentHashMap.java | 6 ++++-- .../util/concurrent/ConcurrentNavigableMap.java | 7 ++++--- .../util/concurrent/ConcurrentSkipListMap.java | 11 ++++++----- 14 files changed, 70 insertions(+), 47 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 02ba232f5fda..38364b4bc078 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -32,6 +32,8 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceale; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -382,7 +384,7 @@ public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { * method will not all return the same set. */ @SideEffectFree - public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied AbstractMap this) { + public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { @@ -449,7 +451,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - public Collection values(@GuardSatisfied AbstractMap this) { + public @PolyShrink Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { @@ -500,7 +502,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - public abstract Set> entrySet(@GuardSatisfied AbstractMap this); + public abstract @PolyShrink Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 02cff3d42106..da1aa1e5848f 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -30,6 +30,8 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -940,7 +942,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied HashMap this) { + public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1074,7 +1076,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - public Collection values(@GuardSatisfied HashMap this) { + public @PolyShrink Collection values(@PolyShrink @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1138,7 +1140,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - public Set> entrySet(@GuardSatisfied HashMap this) { + public @PolyShrink Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index ea3062654645..cad83ff4f55d 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -28,6 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -691,7 +693,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied Hashtable this) { + public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); return keySet; @@ -736,7 +738,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public Set> entrySet(@GuardSatisfied Hashtable this) { + public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); return entrySet; @@ -821,7 +823,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public Collection values(@GuardSatisfied Hashtable this) { + public @PolyShrink Collection values(@PolyShrink @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), this); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index b249b8f1be58..25f0da0c35f3 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -28,6 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; @@ -1016,7 +1018,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied IdentityHashMap this) { + public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1130,7 +1132,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - public Collection values(@GuardSatisfied IdentityHashMap this) { + public @PolyShrink Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1245,7 +1247,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - public Set> entrySet(@GuardSatisfied IdentityHashMap this) { + public @PolyShrink Set> entrySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 8a88fc64f64b..73c9a67b82bd 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -28,6 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -644,7 +646,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - public Set<@KeyFor({"this"}) K> keySet() { + public @PolyShrink Set keySet(@PolyShrink LinkedHashMap this) { return sequencedKeySet(); } @@ -657,7 +659,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return {@inheritDoc} * @since 21 */ - public SequencedSet sequencedKeySet() { + public @PolyShrink SequencedSet sequencedKeySet(@PolyShrink LinkedHashMap this) { Set ks = keySet; if (ks == null) { SequencedSet sks = new LinkedKeySet(false); @@ -798,7 +800,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ - public Collection values() { + public @PolyShrink Collection values(@PolyShrink LinkedHashMap this) { return sequencedValues(); } @@ -811,7 +813,7 @@ public Collection values() { * @return {@inheritDoc} * @since 21 */ - public SequencedCollection sequencedValues() { + public @PolyShrink SequencedCollection sequencedValues(@PolyShrink LinkedHashMap this) { Collection vs = values; if (vs == null) { SequencedCollection svs = new LinkedValues(false); @@ -909,7 +911,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - public Set> entrySet(@GuardSatisfied LinkedHashMap this) { + public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -922,7 +924,7 @@ public SequencedCollection reversed() { * @return {@inheritDoc} * @since 21 */ - public SequencedSet> sequencedEntrySet() { + public @PolyShrink SequencedSet> sequencedEntrySet(@PolyModifiable LinkedHashMap this) { Set> es = entrySet; if (es == null) { SequencedSet> ses = new LinkedEntrySet(false); diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 84f4e94c5127..1600c0c611e1 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -35,6 +35,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -396,7 +397,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @PolyModifiable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @PolyShrink @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -414,7 +415,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @PolyModifiable @PolyNonEmpty Collection values(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @PolyShrink @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -433,7 +434,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @PolyModifiable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @PolyShrink @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 13a51e210e14..e110fe69db53 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -297,7 +298,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - NavigableSet<@KeyFor({"this"}) K> navigableKeySet(); + @PolyShrink NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -314,7 +315,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - NavigableSet<@KeyFor({"this"}) K> descendingKeySet(); + @PolyShrink NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); /** * Returns a view of the portion of this map whose keys range from diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 939a7bd2dbab..8a1f25ebc733 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -30,6 +30,8 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; /** * A Map that has a well-defined encounter order, that supports operations at both ends, and @@ -276,7 +278,7 @@ default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { * * @return a {@code SequencedSet} view of this map's {@code keySet} */ - default SequencedSet sequencedKeySet() { + default @PolyShrink SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { Collection view() { return SequencedMap.this.keySet(); @@ -309,7 +311,7 @@ public int hashCode() { * * @return a {@code SequencedCollection} view of this map's {@code values} collection */ - default SequencedCollection sequencedValues() { + default @PolyShrink SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { Collection view() { return SequencedMap.this.values(); @@ -335,7 +337,7 @@ public SequencedCollection reversed() { * * @return a {@code SequencedSet} view of this map's {@code entrySet} */ - default SequencedSet> sequencedEntrySet() { + default @PolyShrink SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { class SeqEntrySet extends AbstractMap.ViewCollection> implements SequencedSet> { Collection> view() { diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 1b468a3e4b77..4958e5a52acf 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; @@ -261,7 +262,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied SortedMap this); + @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -282,7 +283,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - Collection values(@GuardSatisfied SortedMap this); + @PolyShrink Collection values(@PolyShrink @GuardSatisfied SortedMap this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -303,7 +304,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - Set> entrySet(@GuardSatisfied SortedMap this); + @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** * Throws {@code UnsupportedOperationException}. The encounter order induced by this diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index a96ecfff2bce..11b518caa35e 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -29,6 +29,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -1154,7 +1156,7 @@ public Object clone(@GuardSatisfied TreeMap this) { * operations. It does not support the {@code add} or {@code addAll} * operations. */ - public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied TreeMap this) { + public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1162,7 +1164,7 @@ public Object clone(@GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@GuardSatisfied TreeMap this) { + public @PolyShrink NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } @@ -1171,7 +1173,7 @@ public Object clone(@GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@GuardSatisfied TreeMap this) { + public @PolyShrink NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1196,7 +1198,7 @@ public Object clone(@GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ - public Collection values(@GuardSatisfied TreeMap this) { + public @PolyShrink Collection values(@PolyShrink @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1228,7 +1230,7 @@ public Collection values(@GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public Set> entrySet(@GuardSatisfied TreeMap this) { + public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index caf82fb03918..b83c3e67abac 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -28,6 +28,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -904,7 +906,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied WeakHashMap this) { + public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -963,7 +965,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public Collection values(@GuardSatisfied WeakHashMap this) { + public @PolyShrink Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1014,7 +1016,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public Set> entrySet(@GuardSatisfied WeakHashMap this) { + public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index b7c667428d5a..7985c8ce046c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -38,6 +38,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -1288,7 +1290,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - public Collection values() { + public @PolyShrink Collection values(@PolyShrink ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; return values = new ValuesView(this); @@ -1312,7 +1314,7 @@ public Collection values() { * @return the set view */ @SideEffectFree - public Set> entrySet() { + public @PolyShrink Set> entrySet(@PolyShrink ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index fe8eb9969bd0..cd3d406c2bfd 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -36,6 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.NavigableMap; @@ -144,7 +145,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - NavigableSet navigableKeySet(); + @PolyShrink NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -164,7 +165,7 @@ public interface ConcurrentNavigableMap * * @return a navigable set view of the keys in this map */ - NavigableSet keySet(); + @PolyShrink NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -183,5 +184,5 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - NavigableSet descendingKeySet(); + @PolyShrink NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 0415aa110448..062343c89d66 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; @@ -1632,14 +1633,14 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ - public NavigableSet keySet() { + public @PolyShrink NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); } @SideEffectFree - public NavigableSet navigableKeySet() { + public @PolyShrink NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); @@ -1664,7 +1665,7 @@ public NavigableSet navigableKeySet() { *

The view's iterators and spliterators are * weakly consistent. */ - public Collection values() { + public @PolyShrink Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; return values = new Values<>(this); @@ -1698,7 +1699,7 @@ public Collection values() { * sorted in ascending key order */ @SideEffectFree - public Set> entrySet() { + public @PolyShrink Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1713,7 +1714,7 @@ public ConcurrentNavigableMap descendingMap() { } @SideEffectFree - public NavigableSet descendingKeySet() { + public @PolyShrink NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } From d0b16ee233948f7f7104c6f41d38ee129c21bda6 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 23 Feb 2026 00:58:11 -0800 Subject: [PATCH 033/119] fixed typo in annotation --- src/java.base/share/classes/java/util/ArrayList.java | 2 +- src/java.base/share/classes/java/util/Deque.java | 2 +- src/java.base/share/classes/java/util/Iterator.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index b6beb582e247..bf2fdcdad5c7 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -135,7 +135,7 @@ */ @CFComment("lock/nullness: Permit null elements") @AnnotatedFor({"lock", "nullness", "index"}) -public @Growable @Shrinkable @Replaceable class ArrayList extends AbstractList +public @Modifiable class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @java.io.Serial diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 20bfea32aad5..eca294ff0c7d 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -221,7 +221,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) -public @Growabel @Shrinkable interface Deque extends Queue, SequencedCollection { +public @Growable @Shrinkable interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index 60c3a5d7110f..1d8786ebe8dc 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -27,7 +27,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -117,7 +117,7 @@ public interface Iterator { * been called after the last call to the {@code next} * method */ - default void remove(@Modifiable @GuardSatisfied @CanShrink Iterator this) { + default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { throw new UnsupportedOperationException("remove"); } From d4fccb28438f16fdf8905b530ed38c0dd075526c Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Tue, 24 Feb 2026 23:02:57 -0800 Subject: [PATCH 034/119] added the annotation for list iterator. --- .../share/classes/java/util/ListIterator.java | 10 ++++++---- src/java.base/share/classes/java/util/TreeSet.java | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/ListIterator.java b/src/java.base/share/classes/java/util/ListIterator.java index ae50030ca9ce..098b51abaa26 100644 --- a/src/java.base/share/classes/java/util/ListIterator.java +++ b/src/java.base/share/classes/java/util/ListIterator.java @@ -28,7 +28,9 @@ import org.checkerframework.checker.index.qual.GTENegativeOne; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -167,7 +169,7 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ - void remove(@Modifiable @GuardSatisfied ListIterator this); + void remove(@Shrinkable @GuardSatisfied ListIterator this); /** * Replaces the last element returned by {@link #next} or @@ -189,7 +191,7 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ - void set(@Modifiable @GuardSatisfied ListIterator this, E e); + void set(@Replaceable @GuardSatisfied ListIterator this, E e); /** * Inserts the specified element into the list (optional operation). @@ -211,5 +213,5 @@ public interface ListIterator extends Iterator { * @throws IllegalArgumentException if some aspect of this element * prevents it from being added to this list */ - void add(@Modifiable @GuardSatisfied ListIterator this, E e); + void add(@Growable @GuardSatisfied ListIterator this, E e); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 997cf849f7aa..d96a0455b417 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; From a1507ee61aa0d2e9e0ca906eb371627d829247ab Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 25 Feb 2026 23:57:16 -0800 Subject: [PATCH 035/119] change deque, queue, hashset, and treeset back to mod --- src/java.base/share/classes/java/util/Deque.java | 2 +- src/java.base/share/classes/java/util/HashSet.java | 3 ++- src/java.base/share/classes/java/util/Queue.java | 3 ++- src/java.base/share/classes/java/util/TreeSet.java | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index eca294ff0c7d..196cf0d9a010 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -221,7 +221,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness", "index"}) -public @Growable @Shrinkable interface Deque extends Queue, SequencedCollection { +public @Modifiable interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 3695d763c571..259f0d7802d7 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -106,7 +107,7 @@ */ @AnnotatedFor({"lock", "nullness", "index"}) -public @Growable @Shrinkable class HashSet +public @Modifiable class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index f0d6042647f0..aa7b3a2a2198 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -149,7 +150,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public @Growable @Shrinkable interface Queue extends Collection { +public @Modifiable interface Queue extends Collection { /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index d96a0455b417..51f5cf3c6491 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -114,7 +114,7 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public @Growable @Shrinkable class TreeSet extends AbstractSet +public @Modifiable class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { /** From e804103db2e9b3da87c0acdd367aff5f67edf26c Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sat, 14 Mar 2026 16:50:59 -0700 Subject: [PATCH 036/119] temp commit, trying to figuer out why gradlew assemble for checker framework is too slow. --- .../share/classes/java/lang/Iterable.java | 4 +- .../classes/java/util/AbstractCollection.java | 2 +- .../share/classes/java/util/ArrayList.java | 38 +++++++++---------- .../share/classes/java/util/Collection.java | 2 +- .../share/classes/java/util/HashMap.java | 21 +++++----- .../classes/java/util/IdentityHashMap.java | 2 +- .../classes/java/util/LinkedHashMap.java | 10 ++--- .../share/classes/java/util/Set.java | 2 +- 8 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Iterable.java b/src/java.base/share/classes/java/lang/Iterable.java index 72ae4ad6bc07..25b8ac62b59d 100644 --- a/src/java.base/share/classes/java/lang/Iterable.java +++ b/src/java.base/share/classes/java/lang/Iterable.java @@ -25,7 +25,7 @@ package java.lang; import org.checkerframework.checker.index.qual.PolyGrowShrink; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.common.aliasing.qual.NonLeaked; import org.checkerframework.framework.qual.AnnotatedFor; @@ -52,7 +52,7 @@ public interface Iterable { * * @return an Iterator. */ - @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterable this); + @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterable this); /** * Performs the given action for each element of the {@code Iterable} diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 59acf37dc335..e95aa874bd39 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -104,7 +104,7 @@ protected AbstractCollection() { * @return an iterator over the elements contained in this collection */ @SideEffectFree - public abstract @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractCollection this); + public abstract @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty AbstractCollection this); @Pure public abstract @NonNegative int size(@UnknownModifiability @GuardSatisfied AbstractCollection this); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index bf2fdcdad5c7..5c510d51a77e 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -135,7 +135,7 @@ */ @CFComment("lock/nullness: Permit null elements") @AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class ArrayList extends AbstractList +public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @java.io.Serial @@ -510,7 +510,7 @@ public E getLast() { * @throws IndexOutOfBoundsException {@inheritDoc} */ @SideEffectsOnly("this") - public E set(@GuardSatisfied ArrayList this, @NonNegative int index, E element) { + public E set(@Replaceable @GuardSatisfied ArrayList this, @NonNegative int index, E element) { Objects.checkIndex(index, size); E oldValue = elementData(index); elementData[index] = element; @@ -538,7 +538,7 @@ private void add(E e, Object[] elementData, int s) { */ @SideEffectsOnly("this") @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied ArrayList this, E e) { + public boolean add(@Growable @GuardSatisfied ArrayList this, E e) { modCount++; add(e, elementData, size); return true; @@ -554,7 +554,7 @@ public boolean add(@GuardSatisfied ArrayList this, E e) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @SideEffectsOnly("this") - public void add(@GuardSatisfied ArrayList this, @NonNegative int index, E element) { + public void add(@Growable @GuardSatisfied ArrayList this, @NonNegative int index, E element) { rangeCheckForAdd(index); modCount++; final int s; @@ -573,7 +573,7 @@ public void add(@GuardSatisfied ArrayList this, @NonNegative int index, E ele * * @since 21 */ - public void addFirst(E element) { + public void addFirst(@Growable ArrayList this, E element) { add(0, element); } @@ -582,7 +582,7 @@ public void addFirst(E element) { * * @since 21 */ - public void addLast(E element) { + public void addLast(@Growable ArrayList this, E element) { add(element); } @@ -595,7 +595,7 @@ public void addLast(E element) { * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@GuardSatisfied @CanShrink ArrayList this, @NonNegative int index) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @NonNegative int index) { Objects.checkIndex(index, size); final Object[] es = elementData; @@ -611,7 +611,7 @@ public E remove(@GuardSatisfied @CanShrink ArrayList this, @NonNegative int i * @throws NoSuchElementException {@inheritDoc} * @since 21 */ - public E removeFirst() { + public E removeFirst(@Shrinkable ArrayList this) { if (size == 0) { throw new NoSuchElementException(); } else { @@ -628,7 +628,7 @@ public E removeFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ - public E removeLast() { + public E removeLast(@Shrinkable ArrayList this) { int last = size - 1; if (last < 0) { throw new NoSuchElementException(); @@ -742,7 +742,7 @@ int hashCodeRange(int from, int to) { * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ - public boolean remove(@GuardSatisfied @CanShrink ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { final Object[] es = elementData; final int size = this.size; int i = 0; @@ -778,7 +778,7 @@ private void fastRemove(Object[] es, int i) { * Removes all of the elements from this list. The list will * be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink ArrayList this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayList this) { modCount++; final Object[] es = elementData; for (int to = size, i = size = 0; i < to; i++) @@ -799,7 +799,7 @@ public void clear(@GuardSatisfied @CanShrink ArrayList this) { * @throws NullPointerException if the specified collection is null */ @SideEffectsOnly("this") - public boolean addAll(@GuardSatisfied ArrayList this, Collection c) { + public boolean addAll(@Growable @GuardSatisfied ArrayList this, Collection c) { Object[] a = c.toArray(); modCount++; int numNew = a.length; @@ -830,7 +830,7 @@ public boolean addAll(@GuardSatisfied ArrayList this, Collection * @throws NullPointerException if the specified collection is null */ @SideEffectsOnly("this") - public boolean addAll(@GuardSatisfied ArrayList this, @NonNegative int index, Collection c) { + public boolean addAll(@Growable @GuardSatisfied ArrayList this, @NonNegative int index, Collection c) { rangeCheckForAdd(index); Object[] a = c.toArray(); @@ -866,7 +866,7 @@ public boolean addAll(@GuardSatisfied ArrayList this, @NonNegative int index, * toIndex > size() || * toIndex < fromIndex}) */ - protected void removeRange(@GuardSatisfied @CanShrink ArrayList this, int fromIndex, int toIndex) { + protected void removeRange(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, int fromIndex, int toIndex) { if (fromIndex > toIndex) { throw new IndexOutOfBoundsException( outOfBoundsMsg(fromIndex, toIndex)); @@ -921,7 +921,7 @@ private static String outOfBoundsMsg(int fromIndex, int toIndex) { * or if the specified collection is null * @see Collection#contains(Object) */ - public boolean removeAll(@CanShrink ArrayList this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink ArrayList this, Collection c) { return batchRemove(c, false, 0, size); } @@ -941,7 +941,7 @@ public boolean removeAll(@CanShrink ArrayList this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, Collection c) { return batchRemove(c, true, 0, size); } @@ -1053,7 +1053,7 @@ private void readObject(java.io.ObjectInputStream s) * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink ArrayList this, @NonNegative int index) { + public @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink ArrayList this, @NonNegative int index) { rangeCheckForAdd(index); return new ListItr(index); } @@ -1066,7 +1066,7 @@ private void readObject(java.io.ObjectInputStream s) * * @see #listIterator(int) */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty ArrayList this) { + public @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink ArrayList this) { return new ListItr(0); } @@ -1078,7 +1078,7 @@ private void readObject(java.io.ObjectInputStream s) * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ArrayList this) { + public @PolyModifiable @PolyGrowShrink Iterator iterator(@PolyModifiable @PolyGrowShrink ArrayList this) { return new Itr(); } diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 81e1951c2ad7..bbe27d23ad7d 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -334,7 +334,7 @@ public interface Collection extends Iterable { * @return an {@code Iterator} over the elements in this collection */ @SideEffectFree - @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection this); + @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Collection this); /** * Returns an array containing all of the elements in this collection. diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index da1aa1e5848f..74dbfde388e9 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; @@ -1019,12 +1020,12 @@ T[] valuesToArray(T[] a) { return a; } - final class KeySet extends AbstractSet { + final @Shrinkable class KeySet extends AbstractSet { @Pure public final @NonNegative int size() { return size; } public final void clear() { HashMap.this.clear(); } @SideEffectFree - public final Iterator iterator() { return new KeyIterator(); } + public final @Modifiable Iterator iterator() { return new KeyIterator(); } @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public final boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } @@ -1085,12 +1086,12 @@ public final void forEach(Consumer action) { return vs; } - final class Values extends AbstractCollection { + final @Shrinkable class Values extends AbstractCollection { @Pure public final @NonNegative int size() { return size; } public final void clear() { HashMap.this.clear(); } @SideEffectFree - public final Iterator iterator() { return new ValueIterator(); } + public final @Modifiable Iterator iterator() { return new ValueIterator(); } @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public final boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } @@ -1145,12 +1146,12 @@ public final void forEach(Consumer action) { return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } - final class EntrySet extends AbstractSet> { + final @Shrinkable class EntrySet extends AbstractSet> { @Pure public final @NonNegative int size() { return size; } public final void clear() { HashMap.this.clear(); } @SideEffectFree - public final Iterator> iterator() { + public final @Modifiable Iterator> iterator() { return new EntryIterator(); } @Pure @@ -1632,7 +1633,7 @@ static void putLoadFactor(HashMap map, float lf) { /* ------------------------------------------------------------ */ // iterators - abstract class HashIterator { + abstract @Modifiable class HashIterator { Node next; // next entry to return Node current; // current entry int expectedModCount; // for fast-fail @@ -1680,17 +1681,17 @@ public final void remove() { } } - final class KeyIterator extends HashIterator + final @Modifiable class KeyIterator extends HashIterator implements Iterator { public final K next(@NonEmpty KeyIterator this) { return nextNode().key; } } - final class ValueIterator extends HashIterator + final @Modifiable class ValueIterator extends HashIterator implements Iterator { public final V next(@NonEmpty ValueIterator this) { return nextNode().value; } } - final class EntryIterator extends HashIterator + final @Modifiable class EntryIterator extends HashIterator implements Iterator> { public final Map.Entry next(@NonEmpty EntryIterator this) { return nextNode(); } } diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 25f0da0c35f3..6273126ef957 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -1247,7 +1247,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 73c9a67b82bd..d42224add3a4 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -720,7 +720,7 @@ final class LinkedKeySet extends AbstractSet implements SequencedSet { public final int size() { return size; } public final void clear() { LinkedHashMap.this.clear(); } @SideEffectFree - public final Iterator iterator() { + public final @Modifiable Iterator iterator() { return new LinkedKeyIterator(reversed); } @Pure @@ -1038,7 +1038,7 @@ public void replaceAll(BiFunction function) { // Iterators - abstract class LinkedHashIterator { + abstract @Modifiable class LinkedHashIterator { LinkedHashMap.Entry next; LinkedHashMap.Entry current; int expectedModCount; @@ -1081,19 +1081,19 @@ public final void remove() { } } - final class LinkedKeyIterator extends LinkedHashIterator + final @Modifiable class LinkedKeyIterator extends LinkedHashIterator implements Iterator { LinkedKeyIterator(boolean reversed) { super(reversed); } public final K next(@NonEmpty LinkedKeyIterator this) { return nextNode().getKey(); } } - final class LinkedValueIterator extends LinkedHashIterator + final @Modifiable class LinkedValueIterator extends LinkedHashIterator implements Iterator { LinkedValueIterator(boolean reversed) { super(reversed); } public final V next(@NonEmpty LinkedValueIterator this) { return nextNode().value; } } - final class LinkedEntryIterator extends LinkedHashIterator + final @Modifiable class LinkedEntryIterator extends LinkedHashIterator implements Iterator> { LinkedEntryIterator(boolean reversed) { super(reversed); } public final Map.Entry next(@NonEmpty LinkedEntryIterator this) { return nextNode(); } diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 31a2db1c96a7..888f6f5e64b2 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -184,7 +184,7 @@ public interface Set extends Collection { * @return an iterator over the elements in this set */ @SideEffectFree - @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Set this); + @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Set this); /** * Returns an array containing all of the elements in this set. From 94b7f64d9d93586d62bb677302e0369d3c6f2e55 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 19 Mar 2026 01:00:09 -0700 Subject: [PATCH 037/119] partially done with remove class annotation and annotate the entire class. --- .../share/classes/java/util/ArrayList.java | 16 +++--- .../share/classes/java/util/HashSet.java | 25 +++++---- .../share/classes/java/util/Hashtable.java | 43 +++++++------- .../classes/java/util/LinkedHashSet.java | 24 ++++---- .../share/classes/java/util/TreeSet.java | 47 ++++++++-------- .../share/classes/java/util/Vector.java | 56 ++++++++++--------- .../concurrent/ConcurrentSkipListSet.java | 30 +++++----- 7 files changed, 128 insertions(+), 113 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 5c510d51a77e..95dde7c1a067 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -30,12 +30,10 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -134,7 +132,7 @@ * @since 1.2 */ @CFComment("lock/nullness: Permit null elements") -@AnnotatedFor({"lock", "nullness", "index"}) +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @@ -1243,7 +1241,7 @@ public void add(E e) { * @throws IndexOutOfBoundsException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyGrowShrink List subList(@GuardSatisfied @PolyGrowShrink ArrayList this, @NonNegative int fromIndex, @NonNegative int toIndex) { + public @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink ArrayList this, @NonNegative int fromIndex, @NonNegative int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList<>(this, fromIndex, toIndex); } @@ -1803,7 +1801,7 @@ private static boolean isClear(long[] bits, int i) { * @throws NullPointerException {@inheritDoc} */ @Override - public boolean removeIf(@CanShrink ArrayList this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink ArrayList this, Predicate filter) { return removeIf(filter, 0, size); } @@ -1811,7 +1809,7 @@ public boolean removeIf(@CanShrink ArrayList this, Predicate filte * Removes all elements satisfying the given predicate, from index * i (inclusive) to index end (exclusive). */ - boolean removeIf(@CanShrink ArrayList this, Predicate filter, int i, final int end) { + boolean removeIf(@Shrinkable @CanShrink ArrayList this, Predicate filter, int i, final int end) { Objects.requireNonNull(filter); int expectedModCount = modCount; final Object[] es = elementData; @@ -1846,13 +1844,13 @@ boolean removeIf(@CanShrink ArrayList this, Predicate filter, int @SuppressWarnings({"unchecked"}) @Override - public void replaceAll(UnaryOperator operator) { + public void replaceAll(@Replaceable ArrayList this, UnaryOperator operator) { replaceAllRange(operator, 0, size); // TODO(8203662): remove increment of modCount from ... modCount++; } - private void replaceAllRange(UnaryOperator operator, int i, int end) { + private void replaceAllRange(@Replaceable ArrayList this, UnaryOperator operator, int i, int end) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final Object[] es = elementData; @@ -1864,7 +1862,7 @@ private void replaceAllRange(UnaryOperator operator, int i, int end) { @Override @SuppressWarnings("unchecked") - public void sort(Comparator c) { + public void sort(@Replaceable ArrayList this, Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 259f0d7802d7..9069c6bf4c4f 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -30,7 +30,10 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -106,8 +109,8 @@ * @since 1.2 */ -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class HashSet +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { @@ -123,7 +126,7 @@ * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public HashSet() { + public @Modifiable HashSet() { map = new HashMap<>(); } @@ -136,7 +139,7 @@ public HashSet() { * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -154,7 +157,7 @@ public HashSet() { * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -170,7 +173,7 @@ public HashSet(@NonNegative int initialCapacity, float loadFactor) { * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public HashSet(@NonNegative int initialCapacity) { + public @Modifiable HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -187,7 +190,7 @@ public HashSet(@NonNegative int initialCapacity) { * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } @@ -199,7 +202,7 @@ public HashSet(@NonNegative int initialCapacity) { * @see ConcurrentModificationException */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty HashSet this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty HashSet this) { return map.keySet().iterator(); } @@ -253,7 +256,7 @@ public boolean contains(@GuardSatisfied HashSet this, @GuardSatisfied @Nullab */ @SideEffectsOnly("this") @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied HashSet this, E e) { + public boolean add(@Growable @GuardSatisfied HashSet this, E e) { return map.put(e, PRESENT)==null; } @@ -270,7 +273,7 @@ public boolean add(@GuardSatisfied HashSet this, E e) { * @return {@code true} if the set contained the specified element */ @SideEffectsOnly("this") - public boolean remove(@GuardSatisfied HashSet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied HashSet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return map.remove(o)==PRESENT; } @@ -279,7 +282,7 @@ public boolean remove(@GuardSatisfied HashSet this, @GuardSatisfied @Nullable * The set will be empty after this call returns. */ @SideEffectsOnly("this") - public void clear(@GuardSatisfied HashSet this) { + public void clear(@Shrinkable @GuardSatisfied HashSet this) { map.clear(); } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index cad83ff4f55d..9f8470fafb3f 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -27,9 +27,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -154,8 +157,8 @@ * @since 1.0 */ @CFComment({"lock: This collection can only contain nonnull values"}) -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class Hashtable +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable { @@ -206,7 +209,7 @@ * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive. */ - public Hashtable(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable Hashtable(@NonNegative int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); @@ -228,7 +231,7 @@ public Hashtable(@NonNegative int initialCapacity, float loadFactor) { * @throws IllegalArgumentException if the initial capacity is less * than zero. */ - public Hashtable(@NonNegative int initialCapacity) { + public @Modifiable Hashtable(@NonNegative int initialCapacity) { this(initialCapacity, 0.75f); } @@ -236,7 +239,7 @@ public Hashtable(@NonNegative int initialCapacity) { * Constructs a new, empty hashtable with a default initial capacity (11) * and load factor (0.75). */ - public Hashtable() { + public @Modifiable Hashtable() { this(11, 0.75f); } @@ -249,7 +252,7 @@ public Hashtable() { * @throws NullPointerException if the specified map is null. * @since 1.2 */ - public Hashtable(Map t) { + public @Modifiable Hashtable(Map t) { this(Math.max(2*t.size(), 11), 0.75f); putAll(t); } @@ -260,7 +263,7 @@ public Hashtable(Map t) { * * @param dummy a dummy parameter */ - Hashtable(Void dummy) {} + @Modifiable Hashtable(Void dummy) {} /** * Returns the number of keys in this hashtable. @@ -503,7 +506,7 @@ private void addEntry(int hash, K key, V value, int index) { * @see #get(Object) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public synchronized @Nullable V put(@GuardSatisfied Hashtable this, K key, V value) { + public synchronized @Nullable V put(@Growable @Replaceable @GuardSatisfied Hashtable this, K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); @@ -536,7 +539,7 @@ private void addEntry(int hash, K key, V value, int index) { * or {@code null} if the key did not have a mapping * @throws NullPointerException if the key is {@code null} */ - public synchronized @Nullable V remove(@GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { + public synchronized @Nullable V remove(@Shrinkable @GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @@ -568,7 +571,7 @@ private void addEntry(int hash, K key, V value, int index) { * @throws NullPointerException if the specified map is null * @since 1.2 */ - public synchronized void putAll(@GuardSatisfied Hashtable this, Map t) { + public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable this, Map t) { for (Map.Entry e : t.entrySet()) put(e.getKey(), e.getValue()); } @@ -576,7 +579,7 @@ public synchronized void putAll(@GuardSatisfied Hashtable this, Map this) { + public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) { Entry tab[] = table; for (int index = tab.length; --index >= 0; ) tab[index] = null; @@ -955,7 +958,7 @@ public synchronized void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override - public synchronized void replaceAll(BiFunction function) { + public synchronized void replaceAll(@Replaceable Hashtable this, BiFunction function) { Objects.requireNonNull(function); // explicit check required in case // table is empty. final int expectedModCount = modCount; @@ -976,7 +979,7 @@ public synchronized void replaceAll(BiFunction this, K key, V value) { Objects.requireNonNull(value); // Makes sure the key is not already in the hashtable. @@ -1000,7 +1003,7 @@ public synchronized V putIfAbsent(K key, V value) { } @Override - public synchronized boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Objects.requireNonNull(value); Entry tab[] = table; @@ -1025,7 +1028,7 @@ public synchronized boolean remove(@GuardSatisfied @UnknownSignedness Object key } @Override - public synchronized boolean replace(K key, V oldValue, V newValue) { + public synchronized boolean replace(@Replaceable Hashtable this, K key, V oldValue, V newValue) { Objects.requireNonNull(oldValue); Objects.requireNonNull(newValue); Entry tab[] = table; @@ -1047,7 +1050,7 @@ public synchronized boolean replace(K key, V oldValue, V newValue) { } @Override - public synchronized V replace(K key, V value) { + public synchronized V replace(@Replaceable Hashtable this, K key, V value) { Objects.requireNonNull(value); Entry tab[] = table; int hash = key.hashCode(); @@ -1075,7 +1078,7 @@ public synchronized V replace(K key, V value) { * mapping function modified this map */ @Override - public synchronized @PolyNull V computeIfAbsent(K key, Function mappingFunction) { + public synchronized @PolyNull V computeIfAbsent(@Growable Hashtable this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); Entry tab[] = table; @@ -1111,7 +1114,7 @@ public synchronized V replace(K key, V value) { * remapping function modified this map */ @Override - public synchronized @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { + public synchronized @PolyNull V computeIfPresent(@Shrinkable @Replaceable Hashtable this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Entry tab[] = table; @@ -1153,7 +1156,7 @@ public synchronized V replace(K key, V value) { * remapping function modified this map */ @Override - public synchronized @PolyNull V compute(K key, BiFunction remappingFunction) { + public synchronized @PolyNull V compute(@Modifiable Hashtable this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Entry tab[] = table; @@ -1204,7 +1207,7 @@ public synchronized V replace(K key, V value) { * remapping function modified this map */ @Override - public synchronized @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { + public synchronized @PolyNull V merge(@Modifiable Hashtable this, K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Entry tab[] = table; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 922ea62a85e2..13b934ca653b 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -25,7 +25,9 @@ package java.util; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; @@ -127,8 +129,8 @@ */ @CFComment({"lock/nullness: This class permits null elements"}) -@AnnotatedFor({"lock", "nullness"}) -public @Modifiable class LinkedHashSet +@AnnotatedFor({"lock", "nullness", "modifiability"}) +public class LinkedHashSet extends HashSet implements SequencedSet, Cloneable, java.io.Serializable { @@ -247,7 +249,7 @@ LinkedHashMap map() { * * @since 21 */ - public void addFirst(E e) { + public void addFirst(@Growable LinkedHashSet this, E e) { map().putFirst(e, PRESENT); } @@ -259,7 +261,7 @@ public void addFirst(E e) { * * @since 21 */ - public void addLast(E e) { + public void addLast(@Growable LinkedHashSet this, E e) { map().putLast(e, PRESENT); } @@ -289,7 +291,7 @@ public E getLast() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ - public E removeFirst() { + public E removeFirst(@Shrinkable LinkedHashSet this) { return map().sequencedKeySet().removeFirst(); } @@ -299,7 +301,7 @@ public E removeFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ - public E removeLast() { + public E removeLast(@Shrinkable LinkedHashSet this) { return map().sequencedKeySet().removeLast(); } @@ -316,13 +318,13 @@ public SequencedSet reversed() { class ReverseLinkedHashSetView extends AbstractSet implements SequencedSet { public int size() { return LinkedHashSet.this.size(); } public Iterator iterator() { return map().sequencedKeySet().reversed().iterator(); } - public boolean add(E e) { return LinkedHashSet.this.add(e); } - public void addFirst(E e) { LinkedHashSet.this.addLast(e); } - public void addLast(E e) { LinkedHashSet.this.addFirst(e); } + public boolean add(@Growable ReverseLinkedHashSetView this, E e) { return LinkedHashSet.this.add(e); } + public void addFirst(@Growable ReverseLinkedHashSetView this, E e) { LinkedHashSet.this.addLast(e); } + public void addLast(@Growable ReverseLinkedHashSetView this, E e) { LinkedHashSet.this.addFirst(e); } public E getFirst() { return LinkedHashSet.this.getLast(); } public E getLast() { return LinkedHashSet.this.getFirst(); } - public E removeFirst() { return LinkedHashSet.this.removeLast(); } - public E removeLast() { return LinkedHashSet.this.removeFirst(); } + public E removeFirst(@Shrinkable ReverseLinkedHashSetView this) { return LinkedHashSet.this.removeLast(); } + public E removeLast(@Shrinkable ReverseLinkedHashSetView this) { return LinkedHashSet.this.removeFirst(); } public SequencedSet reversed() { return LinkedHashSet.this; } public Object[] toArray() { return map().keysToArray(new Object[map.size()], true); } public T[] toArray(T[] a) { return map().keysToArray(map.prepareArray(a), true); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 51f5cf3c6491..1c964058b6d3 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -30,7 +30,10 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -113,8 +116,8 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) -@AnnotatedFor({"lock", "nullness"}) -public @Modifiable class TreeSet extends AbstractSet +@AnnotatedFor({"lock", "nullness", "modifiability"}) +public class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { /** @@ -128,7 +131,7 @@ /** * Constructs a set backed by the specified navigable map. */ - TreeSet(NavigableMap m) { + @Modifiable TreeSet(NavigableMap m) { this.m = m; } @@ -145,7 +148,7 @@ * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public TreeSet() { + public @Modifiable TreeSet() { this(new TreeMap<>()); } @@ -162,7 +165,7 @@ public TreeSet() { * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public TreeSet(@Nullable Comparator comparator) { + public @Modifiable TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -180,7 +183,7 @@ public TreeSet(@Nullable Comparator comparator) { * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -192,7 +195,7 @@ public TreeSet(@Nullable Comparator comparator) { * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -203,7 +206,7 @@ public TreeSet(@Nullable Comparator comparator) { * @return an iterator over the elements in this set in ascending order */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty TreeSet this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty TreeSet this) { return m.navigableKeySet().iterator(); } @@ -213,14 +216,14 @@ public TreeSet(@Nullable Comparator comparator) { * @return an iterator over the elements in this set in descending order * @since 1.6 */ - public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty TreeSet this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty TreeSet this) { return m.descendingKeySet().iterator(); } /** * @since 1.6 */ - public NavigableSet descendingSet() { + public @PolyModifiable NavigableSet descendingSet(@PolyModifiable TreeSet this) { return new TreeSet<>(m.descendingMap()); } @@ -284,7 +287,7 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow * does not permit null elements */ @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied TreeSet this, E e) { + public boolean add(@Growable @GuardSatisfied TreeSet this, E e) { return m.put(e, PRESENT)==null; } @@ -305,7 +308,7 @@ public boolean add(@GuardSatisfied TreeSet this, E e) { * and this set uses natural ordering, or its comparator * does not permit null elements */ - public boolean remove(@GuardSatisfied TreeSet this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied TreeSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o)==PRESENT; } @@ -313,7 +316,7 @@ public boolean remove(@GuardSatisfied TreeSet this, @GuardSatisfied @UnknownS * Removes all of the elements from this set. * The set will be empty after this call returns. */ - public void clear(@GuardSatisfied TreeSet this) { + public void clear(@Shrinkable @GuardSatisfied TreeSet this) { m.clear(); } @@ -328,7 +331,7 @@ public void clear(@GuardSatisfied TreeSet this) { * if any element is null and this set uses natural ordering, or * its comparator does not permit null elements */ - public boolean addAll(@GuardSatisfied TreeSet this, Collection c) { + public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection c) { // Use linear-time version if applicable if (m.size()==0 && c.size() > 0 && c instanceof SortedSet && @@ -351,7 +354,7 @@ public boolean addAll(@GuardSatisfied TreeSet this, Collection * @since 1.6 */ @SideEffectFree - public @PolyGrowShrink NavigableSet subSet(@GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean fromInclusive, + public @PolyModifiable @PolyGrowShrink NavigableSet subSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean fromInclusive, @GuardSatisfied E toElement, boolean toInclusive) { return new TreeSet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); @@ -366,7 +369,7 @@ public boolean addAll(@GuardSatisfied TreeSet this, Collection * @since 1.6 */ @SideEffectFree - public @PolyGrowShrink NavigableSet headSet(@GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E toElement, boolean inclusive) { + public @PolyModifiable @PolyGrowShrink NavigableSet headSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E toElement, boolean inclusive) { return new TreeSet<>(m.headMap(toElement, inclusive)); } @@ -379,7 +382,7 @@ public boolean addAll(@GuardSatisfied TreeSet this, Collection * @since 1.6 */ @SideEffectFree - public @PolyGrowShrink NavigableSet tailSet(@GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean inclusive) { + public @PolyModifiable @PolyGrowShrink NavigableSet tailSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean inclusive) { return new TreeSet<>(m.tailMap(fromElement, inclusive)); } @@ -391,7 +394,7 @@ public boolean addAll(@GuardSatisfied TreeSet this, Collection * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public @PolyGrowShrink SortedSet subSet(@GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement) { + public @PolyModifiable @PolyGrowShrink SortedSet subSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement) { return subSet(fromElement, true, toElement, false); } @@ -403,7 +406,7 @@ public boolean addAll(@GuardSatisfied TreeSet this, Collection * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public @PolyGrowShrink SortedSet headSet(@GuardSatisfied @PolyGrowShrink TreeSet this, E toElement) { + public @PolyModifiable @PolyGrowShrink SortedSet headSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, E toElement) { return headSet(toElement, false); } @@ -415,7 +418,7 @@ public boolean addAll(@GuardSatisfied TreeSet this, Collection * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public @PolyGrowShrink SortedSet tailSet(@GuardSatisfied @PolyGrowShrink TreeSet this, E fromElement) { + public @PolyModifiable @PolyGrowShrink SortedSet tailSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, E fromElement) { return tailSet(fromElement, true); } @@ -489,7 +492,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { /** * @since 1.6 */ - public @Nullable E pollFirst(@GuardSatisfied TreeSet this) { + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied TreeSet this) { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } @@ -497,7 +500,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { /** * @since 1.6 */ - public @Nullable E pollLast(@GuardSatisfied TreeSet this) { + public @Nullable E pollLast(@Shrinkable @GuardSatisfied TreeSet this) { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 465c6faefc65..49b80371f705 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -30,7 +30,11 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -110,8 +114,8 @@ * @since 1.0 */ @CFComment({"lock/nullness: permits nullable object"}) -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class Vector +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class Vector extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @@ -549,7 +553,7 @@ public synchronized E lastElement(@NonEmpty Vector this) { * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ - public synchronized void setElementAt(@GuardSatisfied Vector this, E obj, @NonNegative int index) { + public synchronized void setElementAt(@Replaceable @GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); @@ -576,7 +580,7 @@ public synchronized void setElementAt(@GuardSatisfied Vector this, E obj, @No * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ - public synchronized void removeElementAt(@GuardSatisfied @CanShrink Vector this, @NonNegative int index) { + public synchronized void removeElementAt(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); @@ -616,7 +620,7 @@ else if (index < 0) { * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index > size()}) */ - public synchronized void insertElementAt(@GuardSatisfied Vector this, E obj, @NonNegative int index) { + public synchronized void insertElementAt(@Growable @GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); @@ -644,7 +648,7 @@ public synchronized void insertElementAt(@GuardSatisfied Vector this, E obj, * * @param obj the component to be added */ - public synchronized void addElement(@GuardSatisfied Vector this, E obj) { + public synchronized void addElement(@Growable @GuardSatisfied Vector this, E obj) { modCount++; add(obj, elementData, elementCount); } @@ -664,7 +668,7 @@ public synchronized void addElement(@GuardSatisfied Vector this, E obj) { * @return {@code true} if the argument was a component of this * vector; {@code false} otherwise. */ - public synchronized boolean removeElement(@GuardSatisfied @CanShrink Vector this, Object obj) { + public synchronized boolean removeElement(@Shrinkable @GuardSatisfied @CanShrink Vector this, Object obj) { modCount++; int i = indexOf(obj); if (i >= 0) { @@ -680,7 +684,7 @@ public synchronized boolean removeElement(@GuardSatisfied @CanShrink Vector t *

This method is identical in functionality to the {@link #clear} * method (which is part of the {@link List} interface). */ - public synchronized void removeAllElements(@GuardSatisfied @CanShrink Vector this) { + public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrink Vector this) { final Object[] es = elementData; for (int to = elementCount, i = elementCount = 0; i < to; i++) es[i] = null; @@ -799,7 +803,7 @@ public synchronized E get(@GuardSatisfied Vector this, @NonNegative int index * ({@code index < 0 || index >= size()}) * @since 1.2 */ - public synchronized E set(@GuardSatisfied Vector this, @NonNegative int index, E element) { + public synchronized E set(@Replaceable @GuardSatisfied Vector this, @NonNegative int index, E element) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -829,7 +833,7 @@ private void add(E e, Object[] elementData, int s) { */ @SideEffectsOnly("this") @EnsuresNonEmpty("this") - public synchronized boolean add(@GuardSatisfied Vector this, E e) { + public synchronized boolean add(@Growable @GuardSatisfied Vector this, E e) { modCount++; add(e, elementData, elementCount); return true; @@ -846,7 +850,7 @@ public synchronized boolean add(@GuardSatisfied Vector this, E e) { * @return true if the Vector contained the specified element * @since 1.2 */ - public boolean remove(@GuardSatisfied @CanShrink Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeElement(o); } @@ -861,7 +865,7 @@ public boolean remove(@GuardSatisfied @CanShrink Vector this, @GuardSatisfied * ({@code index < 0 || index > size()}) * @since 1.2 */ - public void add(@GuardSatisfied Vector this, @NonNegative int index, E element) { + public void add(@Growable @GuardSatisfied Vector this, @NonNegative int index, E element) { insertElementAt(element, index); } @@ -876,7 +880,7 @@ public void add(@GuardSatisfied Vector this, @NonNegative int index, E elemen * ({@code index < 0 || index >= size()}) * @since 1.2 */ - public synchronized E remove(@GuardSatisfied @CanShrink Vector this, @NonNegative int index) { + public synchronized E remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { modCount++; if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -897,7 +901,7 @@ public synchronized E remove(@GuardSatisfied @CanShrink Vector this, @NonNega * * @since 1.2 */ - public void clear(@GuardSatisfied @CanShrink Vector this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink Vector this) { removeAllElements(); } @@ -931,7 +935,7 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public boolean addAll(@GuardSatisfied Vector this, Collection c) { + public boolean addAll(@Growable @GuardSatisfied Vector this, Collection c) { Object[] a = c.toArray(); modCount++; int numNew = a.length; @@ -965,7 +969,7 @@ public boolean addAll(@GuardSatisfied Vector this, Collection c) * or if the specified collection is null * @since 1.2 */ - public boolean removeAll(@GuardSatisfied @CanShrink Vector this, Collection c) { + public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -989,7 +993,7 @@ public boolean removeAll(@GuardSatisfied @CanShrink Vector this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -999,7 +1003,7 @@ public boolean retainAll(@GuardSatisfied @CanShrink Vector this, Collection this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink Vector this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1068,7 +1072,7 @@ private synchronized boolean bulkRemove(Predicate filter) { * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public synchronized boolean addAll(@GuardSatisfied Vector this, @NonNegative int index, Collection c) { + public synchronized boolean addAll(@Growable @GuardSatisfied Vector this, @NonNegative int index, Collection c) { if (index < 0 || index > elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -1161,7 +1165,7 @@ public synchronized String toString(@GuardSatisfied Vector this) { * {@code (fromIndex > toIndex)} */ @SideEffectFree - public synchronized @PolyGrowShrink List subList(@GuardSatisfied @PolyGrowShrink Vector this, int fromIndex, int toIndex) { + public synchronized @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink Vector this, int fromIndex, int toIndex) { return Collections.synchronizedList(super.subList(fromIndex, toIndex), this); } @@ -1173,7 +1177,7 @@ public synchronized String toString(@GuardSatisfied Vector this) { * This call shortens the list by {@code (toIndex - fromIndex)} elements. * (If {@code toIndex==fromIndex}, this operation has no effect.) */ - protected synchronized void removeRange(@GuardSatisfied @CanShrink Vector this, int fromIndex, int toIndex) { + protected synchronized void removeRange(@Shrinkable @GuardSatisfied @CanShrink Vector this, int fromIndex, int toIndex) { modCount++; shiftTailOverGap(elementData, fromIndex, toIndex); } @@ -1244,7 +1248,7 @@ private void writeObject(java.io.ObjectOutputStream s) * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public synchronized @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink Vector this, @NonNegative int index) { + public synchronized @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink Vector this, @NonNegative int index) { if (index < 0 || index > elementCount) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); @@ -1258,7 +1262,7 @@ private void writeObject(java.io.ObjectOutputStream s) * * @see #listIterator(int) */ - public synchronized @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink Vector this) { + public synchronized @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink Vector this) { return new ListItr(0); } @@ -1270,7 +1274,7 @@ private void writeObject(java.io.ObjectOutputStream s) * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public synchronized @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Vector this) { + public synchronized @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Vector this) { return new Itr(); } @@ -1414,7 +1418,7 @@ public synchronized void forEach(Consumer action) { */ @SuppressWarnings({"unchecked"}) @Override - public synchronized void replaceAll(UnaryOperator operator) { + public synchronized void replaceAll(@Replaceable Vector this, UnaryOperator operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final Object[] es = elementData; @@ -1429,7 +1433,7 @@ public synchronized void replaceAll(UnaryOperator operator) { @SuppressWarnings("unchecked") @Override - public synchronized void sort(Comparator c) { + public synchronized void sort(@Replaceable Vector this, Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c); if (modCount != expectedModCount) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 8e81e599faf1..fd182a645a80 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -37,9 +37,11 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -109,8 +111,8 @@ * @param the type of elements maintained by this set * @since 1.6 */ -@AnnotatedFor({"nullness"}) -public @Modifiable class ConcurrentSkipListSet +@AnnotatedFor({"nullness", "modifiability"}) +public class ConcurrentSkipListSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { @@ -128,7 +130,7 @@ * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public ConcurrentSkipListSet() { + public @Modifiable ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -140,7 +142,7 @@ public ConcurrentSkipListSet() { * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -155,7 +157,7 @@ public ConcurrentSkipListSet(@Nullable Comparator comparator) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public ConcurrentSkipListSet(Collection c) { + public @Modifiable ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -168,7 +170,7 @@ public ConcurrentSkipListSet(Collection c) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public ConcurrentSkipListSet(SortedSet s) { + public @Modifiable ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -176,7 +178,7 @@ public ConcurrentSkipListSet(SortedSet s) { /** * For use by submaps */ - ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -264,7 +266,7 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable ConcurrentSkipListSet this, E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; } @@ -282,14 +284,14 @@ public boolean add(E e) { * with the elements currently in this set * @throws NullPointerException if the specified element is null */ - public boolean remove(@GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@Shrinkable ConcurrentSkipListSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o, Boolean.TRUE); } /** * Removes all of the elements from this set. */ - public void clear() { + public void clear(@Shrinkable ConcurrentSkipListSet this) { m.clear(); } @@ -357,7 +359,7 @@ public boolean equals(@Nullable Object o) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public boolean removeAll(Collection c) { + public boolean removeAll(@Shrinkable ConcurrentSkipListSet this, Collection c) { // Override AbstractSet version to avoid unnecessary call to size() boolean modified = false; for (Object e : c) @@ -400,12 +402,12 @@ public E higher(E e) { return m.higherKey(e); } - public @Nullable E pollFirst() { + public @Nullable E pollFirst(@Shrinkable ConcurrentSkipListSet this) { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } - public @Nullable E pollLast() { + public @Nullable E pollLast(@Shrinkable ConcurrentSkipListSet this) { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } From 47a21d2711c4caa419c4dcfa15557bdb3e3640dd Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Fri, 20 Mar 2026 12:49:07 -0700 Subject: [PATCH 038/119] removed annotation on class and fully annotated the map files. --- .../share/classes/java/util/EnumMap.java | 43 +++++---- .../share/classes/java/util/HashMap.java | 32 ++++--- .../classes/java/util/IdentityHashMap.java | 23 +++-- .../classes/java/util/LinkedHashMap.java | 59 ++++++------ .../share/classes/java/util/TreeMap.java | 91 ++++++++++--------- .../share/classes/java/util/WeakHashMap.java | 25 ++--- .../util/concurrent/ConcurrentHashMap.java | 43 +++++---- .../concurrent/ConcurrentSkipListMap.java | 90 +++++++++--------- 8 files changed, 217 insertions(+), 189 deletions(-) diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 9921309d39a8..1c90d30c7876 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -28,7 +28,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; @@ -97,8 +102,8 @@ * @see EnumSet * @since 1.5 */ -@AnnotatedFor({"nullness", "index"}) -public @Modifiable class EnumMap, V> extends AbstractMap +@AnnotatedFor({"nullness", "index", "modifiability"}) +public class EnumMap, V> extends AbstractMap implements java.io.Serializable, Cloneable { /** @@ -153,7 +158,7 @@ private Object maskNull(@Nullable Object value) { * @param keyType the class object of the key type for this enum map * @throws NullPointerException if {@code keyType} is null */ - public EnumMap(Class keyType) { + public @Modifiable EnumMap(Class keyType) { this.keyType = keyType; keyUniverse = getKeyUniverse(keyType); vals = new Object[keyUniverse.length]; @@ -166,7 +171,7 @@ public EnumMap(Class keyType) { * @param m the enum map from which to initialize this enum map * @throws NullPointerException if {@code m} is null */ - public EnumMap(EnumMap m) { + public @Modifiable EnumMap(EnumMap m) { keyType = m.keyType; keyUniverse = m.keyUniverse; vals = m.vals.clone(); @@ -185,7 +190,7 @@ public EnumMap(EnumMap m) { * {@code EnumMap} instance and contains no mappings * @throws NullPointerException if {@code m} is null */ - public EnumMap(Map m) { + public @Modifiable EnumMap(Map m) { if (m instanceof EnumMap) { EnumMap em = (EnumMap) m; keyType = em.keyType; @@ -288,7 +293,7 @@ private boolean containsMapping(@GuardSatisfied @UnknownSignedness Object key, @ * @throws NullPointerException if the specified key is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(K key, V value) { + public @Nullable V put(@Growable @Replaceable EnumMap this, K key, V value) { typeCheck(key); int index = key.ordinal(); @@ -308,7 +313,7 @@ private boolean containsMapping(@GuardSatisfied @UnknownSignedness Object key, @ * return can also indicate that the map previously associated * {@code null} with the specified key.) */ - public @Nullable V remove(@GuardSatisfied @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable EnumMap this, @GuardSatisfied @UnknownSignedness Object key) { if (!isValidKey(key)) return null; int index = ((Enum)key).ordinal(); @@ -360,7 +365,7 @@ private boolean isValidKey(@GuardSatisfied @UnknownSignedness Object key) { "and vals are private class members for EnumMap and are absent in AbstractMap."}) @SuppressWarnings({"nullness:contracts.precondition.override.invalid"}) @RequiresNonNull({"keyUniverse", "vals"}) - public void putAll(@UnknownInitialization EnumMap this, Map m) { + public void putAll(@Growable @Replaceable @UnknownInitialization EnumMap this, Map m) { if (m instanceof EnumMap em) { if (em.keyType != keyType) { if (em.isEmpty()) @@ -384,7 +389,7 @@ public void putAll(@UnknownInitialization EnumMap this, Map this) { Arrays.fill(vals, null); size = 0; } @@ -407,7 +412,7 @@ public void clear() { * * @return a set view of the keys contained in this enum map */ - public Set keySet() { + public @PolyShrink Set keySet(@PolyShrink EnumMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -430,12 +435,12 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } - public boolean remove(@Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable KeySet this, @Nullable @UnknownSignedness Object o) { int oldSize = size; EnumMap.this.remove(o); return size != oldSize; } - public void clear() { + public void clear(@Shrinkable KeySet this) { EnumMap.this.clear(); } } @@ -450,7 +455,7 @@ public void clear() { * * @return a collection view of the values contained in this map */ - public Collection values() { + public @PolyShrink Collection values(@PolyShrink EnumMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -473,7 +478,7 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } - public boolean remove(@Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable Values this, @Nullable @UnknownSignedness Object o) { o = maskNull(o); for (int i = 0; i < vals.length; i++) { @@ -485,7 +490,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { } return false; } - public void clear() { + public void clear(@Shrinkable Values this) { EnumMap.this.clear(); } } @@ -500,7 +505,7 @@ public void clear() { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - public Set> entrySet() { + public @PolyShrink Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) return es; @@ -520,7 +525,7 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return o instanceof Map.Entry entry && containsMapping(entry.getKey(), entry.getValue()); } - public boolean remove(@Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable EntrySet this, @Nullable @UnknownSignedness Object o) { return o instanceof Map.Entry entry && removeMapping(entry.getKey(), entry.getValue()); } @@ -528,7 +533,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { public @NonNegative int size() { return size; } - public void clear() { + public void clear(@Shrinkable EntrySet this) { EnumMap.this.clear(); } @SideEffectFree @@ -580,7 +585,7 @@ public boolean hasNext() { return index != vals.length; } - public void remove() { + public void remove(@Shrinkable EnumMapIterator this) { checkLastReturnedIndex(); if (vals[lastReturnedIndex] != null) { diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 74dbfde388e9..1de279204ced 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -33,6 +33,8 @@ import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -160,8 +162,8 @@ * @see Hashtable * @since 1.2 */ -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class HashMap extends AbstractMap +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class HashMap extends AbstractMap implements Map, Cloneable, Serializable { @java.io.Serial @@ -646,7 +648,7 @@ public boolean containsKey(@GuardSatisfied HashMap this, @GuardSatisfied @ * previously associated {@code null} with {@code key}.) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(@GuardSatisfied HashMap this, K key, V value) { + public @Nullable V put(@Growable @Replaceable @GuardSatisfied HashMap this, K key, V value) { return putVal(hash(key), key, value, false, true); } @@ -820,7 +822,7 @@ else if ((e = tab[index = (n - 1) & hash]) != null) { * @param m mappings to be stored in this map * @throws NullPointerException if the specified map is null */ - public void putAll(@GuardSatisfied HashMap this, Map m) { + public void putAll(@Growable @Replaceable @GuardSatisfied HashMap this, Map m) { putMapEntries(m, true); } @@ -833,7 +835,7 @@ public void putAll(@GuardSatisfied HashMap this, Map this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable @GuardSatisfied HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Node e; return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value; @@ -894,7 +896,7 @@ else if (node == p) * Removes all of the mappings from this map. * The map will be empty after this call returns. */ - public void clear(@GuardSatisfied HashMap this) { + public void clear(@Shrinkable @GuardSatisfied HashMap this) { Node[] tab; modCount++; if ((tab = table) != null && size > 0) { @@ -1202,17 +1204,17 @@ public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override - public @Nullable V putIfAbsent(K key, V value) { + public @Nullable V putIfAbsent(@Growable HashMap this, K key, V value) { return putVal(hash(key), key, value, true, true); } @Override - public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { + public boolean remove(@Shrinkable HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return removeNode(hash(key), key, value, true, true) != null; } @Override - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable HashMap this, K key, V oldValue, V newValue) { Node e; V v; if ((e = getNode(key)) != null && ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) { @@ -1224,7 +1226,7 @@ public boolean replace(K key, V oldValue, V newValue) { } @Override - public @Nullable V replace(K key, V value) { + public @Nullable V replace(@Replaceable HashMap this, K key, V value) { Node e; if ((e = getNode(key)) != null) { V oldValue = e.value; @@ -1246,7 +1248,7 @@ public boolean replace(K key, V oldValue, V newValue) { * mapping function modified this map */ @Override - public @PolyNull V computeIfAbsent(K key, + public @PolyNull V computeIfAbsent(@Growable HashMap this, K key, Function mappingFunction) { if (mappingFunction == null) throw new NullPointerException(); @@ -1312,7 +1314,7 @@ else if (t != null) * remapping function modified this map */ @Override - public @PolyNull V computeIfPresent(K key, + public @PolyNull V computeIfPresent(@Shrinkable @Replaceable HashMap this, K key, BiFunction remappingFunction) { if (remappingFunction == null) throw new NullPointerException(); @@ -1346,7 +1348,7 @@ else if (t != null) * remapping function modified this map */ @Override - public @PolyNull V compute(K key, + public @PolyNull V compute(@Modifiable HashMap this, K key, BiFunction remappingFunction) { if (remappingFunction == null) throw new NullPointerException(); @@ -1411,7 +1413,7 @@ else if (v != null) { * remapping function modified this map */ @Override - public @PolyNull V merge(K key, @NonNull V value, + public @PolyNull V merge(@Modifiable HashMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (value == null || remappingFunction == null) throw new NullPointerException(); @@ -1488,7 +1490,7 @@ public void forEach(BiConsumer action) { } @Override - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable HashMap this, BiFunction function) { Node[] tab; if (function == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 6273126ef957..ccd323ff0e9c 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -27,9 +27,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; @@ -167,8 +170,8 @@ */ @CFComment({"lock/nullness: This collection can only contain null values"}) -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class IdentityHashMap +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class IdentityHashMap extends AbstractMap implements Map, java.io.Serializable, Cloneable { @@ -294,7 +297,7 @@ private void init(int initCapacity) { * @param m the map whose mappings are to be placed into this map * @throws NullPointerException if the specified map is null */ - public IdentityHashMap(Map m) { + public @Modifiable IdentityHashMap(Map m) { // Allow for a bit of growth this((int) ((1 + m.size()) * 1.1)); putAll(m); @@ -460,7 +463,7 @@ private boolean containsMapping(@UnknownSignedness @GuardSatisfied @Nullable Obj * @see #containsKey(Object) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(@GuardSatisfied IdentityHashMap this, K key, V value) { + public @Nullable V put(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, K key, V value) { final Object k = maskNull(key); retryAfterResize: for (;;) { @@ -541,7 +544,7 @@ private boolean resize(int newCapacity) { * @param m mappings to be stored in this map * @throws NullPointerException if the specified map is null */ - public void putAll(@GuardSatisfied IdentityHashMap this, Map m) { + public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, Map m) { int n = m.size(); if (n == 0) return; @@ -563,7 +566,7 @@ public void putAll(@GuardSatisfied IdentityHashMap this, Map this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable @GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); Object[] tab = table; int len = tab.length; @@ -659,7 +662,7 @@ private void closeDeletion(int d) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ - public void clear(@GuardSatisfied IdentityHashMap this) { + public void clear(@Shrinkable @GuardSatisfied IdentityHashMap this) { modCount++; Object[] tab = table; for (int i = 0; i < tab.length; i++) @@ -1442,7 +1445,7 @@ public void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable IdentityHashMap this, BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; @@ -1469,7 +1472,7 @@ public void replaceAll(BiFunction function) { * {@code false}. */ @Override - public boolean remove(Object key, Object value) { + public boolean remove(@Shrinkable IdentityHashMap this, Object key, Object value) { return removeMapping(key, value); } @@ -1483,7 +1486,7 @@ public boolean remove(Object key, Object value) { * otherwise it returns {@code false}. */ @Override - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable IdentityHashMap this, K key, V oldValue, V newValue) { Object k = maskNull(key); Object[] tab = table; int len = tab.length; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index d42224add3a4..34f72f2b77d2 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -27,9 +27,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -190,8 +193,8 @@ * @see Hashtable * @since 1.4 */ -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class LinkedHashMap +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class LinkedHashMap extends HashMap implements SequencedMap { @@ -407,7 +410,7 @@ void afterNodeAccess(Node e) { * * @since 21 */ - public V putFirst(K k, V v) { + public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { try { putMode = PUT_FIRST; return this.put(k, v); @@ -424,7 +427,7 @@ public V putFirst(K k, V v) { * * @since 21 */ - public V putLast(K k, V v) { + public V putLast(@Growable @Replaceable LinkedHashMap this, K k, V v) { try { putMode = PUT_LAST; return this.put(k, v); @@ -453,7 +456,7 @@ void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); accessOrder = false; } @@ -469,7 +472,7 @@ public LinkedHashMap(@NonNegative int initialCapacity, float loadFactor) { * @param initialCapacity the initial capacity * @throws IllegalArgumentException if the initial capacity is negative */ - public LinkedHashMap(@NonNegative int initialCapacity) { + public @Modifiable LinkedHashMap(@NonNegative int initialCapacity) { super(initialCapacity); accessOrder = false; } @@ -478,7 +481,7 @@ public LinkedHashMap(@NonNegative int initialCapacity) { * Constructs an empty insertion-ordered {@code LinkedHashMap} instance * with the default initial capacity (16) and load factor (0.75). */ - public LinkedHashMap() { + public @Modifiable LinkedHashMap() { super(); accessOrder = false; } @@ -492,7 +495,7 @@ public LinkedHashMap() { * @param m the map whose mappings are to be placed in this map * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty LinkedHashMap(@PolyNonEmpty Map m) { + public @Modifiable @PolyNonEmpty LinkedHashMap(@PolyNonEmpty Map m) { super(); accessOrder = false; putMapEntries(m, false); @@ -509,7 +512,7 @@ public LinkedHashMap() { * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ - public LinkedHashMap(@NonNegative int initialCapacity, + public @Modifiable LinkedHashMap(@NonNegative int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); @@ -576,7 +579,7 @@ public V getOrDefault(@Nullable Object key, V defaultValue) { /** * {@inheritDoc} */ - public void clear(@GuardSatisfied LinkedHashMap this) { + public void clear(@Shrinkable @GuardSatisfied LinkedHashMap this) { super.clear(); head = tail = null; } @@ -1026,7 +1029,7 @@ public void forEach(BiConsumer action) { throw new ConcurrentModificationException(); } - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable LinkedHashMap this, BiFunction function) { if (function == null) throw new NullPointerException(); int mc = modCount; @@ -1176,19 +1179,19 @@ public V get(Object key) { return base.get(key); } - public V put(K key, V value) { + public V put(@Growable @Replaceable ReversedLinkedHashMapView this, K key, V value) { return base.put(key, value); } - public V remove(Object key) { + public V remove(@Shrinkable ReversedLinkedHashMapView this, Object key) { return base.remove(key); } - public void putAll(Map m) { + public void putAll(@Growable @Replaceable ReversedLinkedHashMapView this, Map m) { base.putAll(m); } - public void clear() { + public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } @@ -1218,7 +1221,7 @@ public void forEach(BiConsumer action) { throw new ConcurrentModificationException(); } - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable ReversedLinkedHashMapView this, BiFunction function) { if (function == null) throw new NullPointerException(); int mc = base.modCount; @@ -1228,35 +1231,35 @@ public void replaceAll(BiFunction function) { throw new ConcurrentModificationException(); } - public V putIfAbsent(K key, V value) { + public V putIfAbsent(@Growable ReversedLinkedHashMapView this, K key, V value) { return base.putIfAbsent(key, value); } - public boolean remove(Object key, Object value) { + public boolean remove(@Shrinkable ReversedLinkedHashMapView this, Object key, Object value) { return base.remove(key, value); } - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable ReversedLinkedHashMapView this, K key, V oldValue, V newValue) { return base.replace(key, oldValue, newValue); } - public V replace(K key, V value) { + public V replace(@Replaceable ReversedLinkedHashMapView this, K key, V value) { return base.replace(key, value); } - public V computeIfAbsent(K key, Function mappingFunction) { + public V computeIfAbsent(@Growable ReversedLinkedHashMapView this, K key, Function mappingFunction) { return base.computeIfAbsent(key, mappingFunction); } - public V computeIfPresent(K key, BiFunction remappingFunction) { + public V computeIfPresent(@Shrinkable @Replaceable ReversedLinkedHashMapView this, K key, BiFunction remappingFunction) { return base.computeIfPresent(key, remappingFunction); } - public V compute(K key, BiFunction remappingFunction) { + public V compute(@Modifiable ReversedLinkedHashMapView this, K key, BiFunction remappingFunction) { return base.compute(key, remappingFunction); } - public V merge(K key, V value, BiFunction remappingFunction) { + public V merge(@Modifiable ReversedLinkedHashMapView this, K key, V value, BiFunction remappingFunction) { return base.merge(key, value, remappingFunction); } @@ -1274,19 +1277,19 @@ public Entry lastEntry() { return base.firstEntry(); } - public Entry pollFirstEntry() { + public Entry pollFirstEntry(@Shrinkable ReversedLinkedHashMapView this) { return base.pollLastEntry(); } - public Entry pollLastEntry() { + public Entry pollLastEntry(@Shrinkable ReversedLinkedHashMapView this) { return base.pollFirstEntry(); } - public V putFirst(K k, V v) { + public V putFirst(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { return base.putLast(k, v); } - public V putLast(K k, V v) { + public V putLast(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { return base.putFirst(k, v); } } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 11b518caa35e..310920f61f3c 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -27,10 +27,13 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -142,8 +145,8 @@ */ @CFComment({"lock/nullness: This permits null element when using a custom comparator that allows null"}) -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class TreeMap +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java.io.Serializable { @@ -180,7 +183,7 @@ * {@code put(Object key, Object value)} call will throw a * {@code ClassCastException}. */ - public TreeMap() { + public @Modifiable TreeMap() { comparator = null; } @@ -198,7 +201,7 @@ public TreeMap() { * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ - public TreeMap(@Nullable Comparator comparator) { + public @Modifiable TreeMap(@Nullable Comparator comparator) { this.comparator = comparator; } @@ -216,7 +219,7 @@ public TreeMap(@Nullable Comparator comparator) { * or are not mutually comparable * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { + public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { comparator = null; putAll(m); } @@ -230,7 +233,7 @@ public TreeMap(@Nullable Comparator comparator) { * and whose comparator is to be used to sort this map * @throws NullPointerException if the specified map is null */ - public @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { + public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); @@ -375,7 +378,7 @@ public V putLast(K k, V v) { * the specified map contains a null key and this map does not * permit null keys */ - public void putAll(@GuardSatisfied TreeMap this, Map map) { + public void putAll(@Growable @Replaceable @GuardSatisfied TreeMap this, Map map) { int mapSize = map.size(); if (size==0 && mapSize!=0 && map instanceof SortedMap) { if (Objects.equals(comparator, ((SortedMap)map).comparator())) { @@ -596,12 +599,12 @@ final Entry getLowerEntry(K key) { * does not permit null keys */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(@GuardSatisfied TreeMap this, K key, V value) { + public @Nullable V put(@Growable @Replaceable @GuardSatisfied TreeMap this, K key, V value) { return put(key, value, true); } @Override - public V putIfAbsent(K key, V value) { + public V putIfAbsent(@Growable TreeMap this, K key, V value) { return put(key, value, false); } @@ -616,7 +619,7 @@ public V putIfAbsent(K key, V value) { * mapping function modified this map */ @Override - public V computeIfAbsent(K key, Function mappingFunction) { + public V computeIfAbsent(@Growable TreeMap this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V newValue; Entry t = root; @@ -686,7 +689,7 @@ else if (cmp > 0) * remapping function modified this map */ @Override - public V computeIfPresent(K key, BiFunction remappingFunction) { + public V computeIfPresent(@Shrinkable @Replaceable TreeMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Entry oldEntry = getEntry(key); if (oldEntry != null && oldEntry.value != null) { @@ -707,7 +710,7 @@ public V computeIfPresent(K key, BiFunction r * remapping function modified this map */ @Override - public V compute(K key, BiFunction remappingFunction) { + public V compute(@Modifiable TreeMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V newValue; Entry t = root; @@ -769,7 +772,7 @@ else if (cmp > 0) * remapping function modified this map */ @Override - public V merge(K key, V value, BiFunction remappingFunction) { + public V merge(@Modifiable TreeMap this, K key, V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); Entry t = root; @@ -943,7 +946,7 @@ private V mergeValue(Entry t, V value, BiFunction this, @GuardSatisfied @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable @GuardSatisfied TreeMap this, @GuardSatisfied @UnknownSignedness Object key) { Entry p = getEntry(key); if (p == null) return null; @@ -957,7 +960,7 @@ private V mergeValue(Entry t, V value, BiFunction this) { + public void clear(@Shrinkable @GuardSatisfied TreeMap this) { modCount++; size = 0; root = null; @@ -1013,7 +1016,7 @@ public Object clone(@GuardSatisfied TreeMap this) { /** * @since 1.6 */ - public Map.@Nullable Entry pollFirstEntry(@GuardSatisfied TreeMap this) { + public Map.@Nullable Entry pollFirstEntry(@Shrinkable @GuardSatisfied TreeMap this) { Entry p = getFirstEntry(); Map.Entry result = exportEntry(p); if (p != null) @@ -1024,7 +1027,7 @@ public Object clone(@GuardSatisfied TreeMap this) { /** * @since 1.6 */ - public Map.@Nullable Entry pollLastEntry(@GuardSatisfied TreeMap this) { + public Map.@Nullable Entry pollLastEntry(@Shrinkable @GuardSatisfied TreeMap this) { Entry p = getLastEntry(); Map.Entry result = exportEntry(p); if (p != null) @@ -1239,7 +1242,7 @@ public Object clone(@GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public NavigableMap descendingMap(@GuardSatisfied TreeMap this) { + public @PolyModifiable NavigableMap descendingMap(@PolyModifiable @GuardSatisfied TreeMap this) { NavigableMap km = descendingMap; return (km != null) ? km : (descendingMap = new DescendingSubMap<>(this, @@ -1256,7 +1259,7 @@ public NavigableMap descendingMap(@GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public NavigableMap subMap(@GuardSatisfied TreeMap this, @GuardSatisfied K fromKey, boolean fromInclusive, + public @PolyModifiable NavigableMap subMap(@PolyModifiable @GuardSatisfied TreeMap this, @GuardSatisfied K fromKey, boolean fromInclusive, @GuardSatisfied K toKey, boolean toInclusive) { return new AscendingSubMap<>(this, false, fromKey, fromInclusive, @@ -1272,7 +1275,7 @@ public NavigableMap subMap(@GuardSatisfied TreeMap this, @GuardSatisf * @since 1.6 */ @SideEffectFree - public NavigableMap headMap(@GuardSatisfied TreeMap this, @GuardSatisfied K toKey, boolean inclusive) { + public @PolyModifiable NavigableMap headMap(@PolyModifiable @GuardSatisfied TreeMap this, @GuardSatisfied K toKey, boolean inclusive) { return new AscendingSubMap<>(this, true, null, true, false, toKey, inclusive); @@ -1287,7 +1290,7 @@ public NavigableMap headMap(@GuardSatisfied TreeMap this, @GuardSatis * @since 1.6 */ @SideEffectFree - public NavigableMap tailMap(@GuardSatisfied TreeMap this, @GuardSatisfied K fromKey, boolean inclusive) { + public @PolyModifiable NavigableMap tailMap(@PolyModifiable @GuardSatisfied TreeMap this, @GuardSatisfied K fromKey, boolean inclusive) { return new AscendingSubMap<>(this, false, fromKey, inclusive, true, null, true); @@ -1301,7 +1304,7 @@ public NavigableMap tailMap(@GuardSatisfied TreeMap this, @GuardSatis * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public SortedMap subMap(@GuardSatisfied TreeMap this, @GuardSatisfied K fromKey, @GuardSatisfied K toKey) { + public @PolyModifiable SortedMap subMap(@PolyModifiable @GuardSatisfied TreeMap this, @GuardSatisfied K fromKey, @GuardSatisfied K toKey) { return subMap(fromKey, true, toKey, false); } @@ -1313,7 +1316,7 @@ public SortedMap subMap(@GuardSatisfied TreeMap this, @GuardSatisfied * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public SortedMap headMap(@GuardSatisfied TreeMap this, K toKey) { + public @PolyModifiable SortedMap headMap(@PolyModifiable @GuardSatisfied TreeMap this, K toKey) { return headMap(toKey, false); } @@ -1325,12 +1328,12 @@ public SortedMap headMap(@GuardSatisfied TreeMap this, K toKey) { * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public SortedMap tailMap(@GuardSatisfied TreeMap this, K fromKey) { + public @PolyModifiable SortedMap tailMap(@PolyModifiable @GuardSatisfied TreeMap this, K fromKey) { return tailMap(fromKey, true); } @Override - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable TreeMap this, K key, V oldValue, V newValue) { Entry p = getEntry(key); if (p!=null && Objects.equals(oldValue, p.value)) { p.value = newValue; @@ -1340,7 +1343,7 @@ public boolean replace(K key, V oldValue, V newValue) { } @Override - public V replace(K key, V value) { + public V replace(@Replaceable TreeMap this, K key, V value) { Entry p = getEntry(key); if (p!=null) { V oldValue = p.value; @@ -1364,7 +1367,7 @@ public void forEach(BiConsumer action) { } @Override - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable TreeMap this, BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; @@ -1893,25 +1896,25 @@ public final boolean containsKey(@UnknownSignedness Object key) { } @EnsuresKeyFor(value={"#1"}, map={"this"}) - public final V put(K key, V value) { + public final V put(@Growable @Replaceable NavigableSubMap this, K key, V value) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.put(key, value); } - public V putIfAbsent(K key, V value) { + public V putIfAbsent(@Growable NavigableSubMap this, K key, V value) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.putIfAbsent(key, value); } - public V merge(K key, V value, BiFunction remappingFunction) { + public V merge(@Modifiable NavigableSubMap this, K key, V value, BiFunction remappingFunction) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.merge(key, value, remappingFunction); } - public V computeIfAbsent(K key, Function mappingFunction) { + public V computeIfAbsent(@Growable NavigableSubMap this, K key, Function mappingFunction) { if (!inRange(key)) { // Do not throw if mapping function returns null // to preserve compatibility with default computeIfAbsent implementation @@ -1921,7 +1924,7 @@ public V computeIfAbsent(K key, Function mappingFunction return m.computeIfAbsent(key, mappingFunction); } - public V compute(K key, BiFunction remappingFunction) { + public V compute(@Modifiable NavigableSubMap this, K key, BiFunction remappingFunction) { if (!inRange(key)) { // Do not throw if remapping function returns null // to preserve compatibility with default computeIfAbsent implementation @@ -1931,7 +1934,7 @@ public V compute(K key, BiFunction remappingF return m.compute(key, remappingFunction); } - public V computeIfPresent(K key, BiFunction remappingFunction) { + public V computeIfPresent(@Shrinkable @Replaceable NavigableSubMap this, K key, BiFunction remappingFunction) { return !inRange(key) ? null : m.computeIfPresent(key, remappingFunction); } @@ -1939,7 +1942,7 @@ public final V get(Object key) { return !inRange(key) ? null : m.get(key); } - public final V remove(Object key) { + public final V remove(@Shrinkable NavigableSubMap this, Object key) { return !inRange(key) ? null : m.remove(key); } @@ -1991,7 +1994,7 @@ public final Map.Entry lastEntry() { return exportEntry(subHighest()); } - public final Map.Entry pollFirstEntry() { + public final Map.Entry pollFirstEntry(@Shrinkable NavigableSubMap this) { TreeMap.Entry e = subLowest(); Map.Entry result = exportEntry(e); if (e != null) @@ -1999,7 +2002,7 @@ public final Map.Entry pollFirstEntry() { return result; } - public final Map.Entry pollLastEntry() { + public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) { TreeMap.Entry e = subHighest(); Map.Entry result = exportEntry(e); if (e != null) @@ -2291,7 +2294,7 @@ public Comparator comparator() { } @SideEffectFree - public NavigableMap subMap(K fromKey, boolean fromInclusive, + public @PolyModifiable NavigableMap subMap(@PolyModifiable AscendingSubMap this, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { if (!inRange(fromKey, fromInclusive)) throw new IllegalArgumentException("fromKey out of range"); @@ -2303,7 +2306,7 @@ public NavigableMap subMap(K fromKey, boolean fromInclusive, } @SideEffectFree - public NavigableMap headMap(K toKey, boolean inclusive) { + public @PolyModifiable NavigableMap headMap(@PolyModifiable AscendingSubMap this, K toKey, boolean inclusive) { if (!inRange(toKey, inclusive)) throw new IllegalArgumentException("toKey out of range"); return new AscendingSubMap<>(m, @@ -2312,7 +2315,7 @@ public NavigableMap headMap(K toKey, boolean inclusive) { } @SideEffectFree - public NavigableMap tailMap(K fromKey, boolean inclusive) { + public @PolyModifiable NavigableMap tailMap(@PolyModifiable AscendingSubMap this, K fromKey, boolean inclusive) { if (!inRange(fromKey, inclusive)) throw new IllegalArgumentException("fromKey out of range"); return new AscendingSubMap<>(m, @@ -2321,7 +2324,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { } @SideEffectFree - public NavigableMap descendingMap() { + public @PolyModifiable NavigableMap descendingMap(@PolyModifiable AscendingSubMap this) { NavigableMap mv = descendingMapView; return (mv != null) ? mv : (descendingMapView = @@ -2383,7 +2386,7 @@ public Comparator comparator() { } @SideEffectFree - public NavigableMap subMap(K fromKey, boolean fromInclusive, + public @PolyModifiable NavigableMap subMap(@PolyModifiable DescendingSubMap this, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { if (!inRange(fromKey, fromInclusive)) throw new IllegalArgumentException("fromKey out of range"); @@ -2395,7 +2398,7 @@ public NavigableMap subMap(K fromKey, boolean fromInclusive, } @SideEffectFree - public NavigableMap headMap(K toKey, boolean inclusive) { + public @PolyModifiable NavigableMap headMap(@PolyModifiable DescendingSubMap this, K toKey, boolean inclusive) { if (!inRange(toKey, inclusive)) throw new IllegalArgumentException("toKey out of range"); return new DescendingSubMap<>(m, @@ -2404,7 +2407,7 @@ public NavigableMap headMap(K toKey, boolean inclusive) { } @SideEffectFree - public NavigableMap tailMap(K fromKey, boolean inclusive) { + public @PolyModifiable NavigableMap tailMap(@PolyModifiable DescendingSubMap this, K fromKey, boolean inclusive) { if (!inRange(fromKey, inclusive)) throw new IllegalArgumentException("fromKey out of range"); return new DescendingSubMap<>(m, @@ -2413,7 +2416,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { } @SideEffectFree - public NavigableMap descendingMap() { + public @PolyModifiable NavigableMap descendingMap(@PolyModifiable DescendingSubMap this) { NavigableMap mv = descendingMapView; return (mv != null) ? mv : (descendingMapView = diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index b83c3e67abac..8f17e4c9a8c8 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -27,9 +27,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -153,8 +156,8 @@ * @see java.lang.ref.WeakReference */ @CFComment({"lock: permits null keys and values"}) -@AnnotatedFor({"lock", "index", "nullness"}) -public @Modifiable class WeakHashMap +@AnnotatedFor({"lock", "index", "nullness", "modifiability"}) +public class WeakHashMap extends AbstractMap implements Map { @@ -229,7 +232,7 @@ private Entry[] newTable(int n) { * @throws IllegalArgumentException if the initial capacity is negative, * or if the load factor is nonpositive. */ - public WeakHashMap(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable WeakHashMap(@NonNegative int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Initial Capacity: "+ initialCapacity); @@ -256,7 +259,7 @@ public WeakHashMap(@NonNegative int initialCapacity, float loadFactor) { * @param initialCapacity The initial capacity of the {@code WeakHashMap} * @throws IllegalArgumentException if the initial capacity is negative */ - public WeakHashMap(@NonNegative int initialCapacity) { + public @Modifiable WeakHashMap(@NonNegative int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } @@ -264,7 +267,7 @@ public WeakHashMap(@NonNegative int initialCapacity) { * Constructs a new, empty {@code WeakHashMap} with the default initial * capacity (16) and load factor (0.75). */ - public WeakHashMap() { + public @Modifiable WeakHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); } @@ -278,7 +281,7 @@ public WeakHashMap() { * @throws NullPointerException if the specified map is null * @since 1.3 */ - public @PolyNonEmpty WeakHashMap(@PolyNonEmpty Map m) { + public @Modifiable @PolyNonEmpty WeakHashMap(@PolyNonEmpty Map m) { this(Math.max((int) Math.ceil(m.size() / (double)DEFAULT_LOAD_FACTOR), DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); @@ -485,7 +488,7 @@ Entry getEntry(Object key) { * previously associated {@code null} with {@code key}.) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(@GuardSatisfied WeakHashMap this, K key, V value) { + public @Nullable V put(@Growable @Replaceable @GuardSatisfied WeakHashMap this, K key, V value) { Object k = maskNull(key); int h = hash(k); Entry[] tab = getTable(); @@ -577,7 +580,7 @@ private void transfer(Entry[] src, Entry[] dest) { * @param m mappings to be stored in this map. * @throws NullPointerException if the specified map is null. */ - public void putAll(@GuardSatisfied WeakHashMap this, Map m) { + public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this, Map m) { int numKeysToBeAdded = m.size(); if (numKeysToBeAdded == 0) return; @@ -626,7 +629,7 @@ public void putAll(@GuardSatisfied WeakHashMap this, Map this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable @GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); int h = hash(k); Entry[] tab = getTable(); @@ -685,7 +688,7 @@ boolean removeMapping(Object o) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ - public void clear(@GuardSatisfied WeakHashMap this) { + public void clear(@Shrinkable @GuardSatisfied WeakHashMap this) { // clear out ref queue. We don't need to expunge entries // since table is getting cleared. while (queue.poll() != null) @@ -1095,7 +1098,7 @@ public void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable WeakHashMap this, BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 7985c8ce046c..1affce11f660 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -36,10 +36,13 @@ package java.util.concurrent; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -283,8 +286,8 @@ * @param the type of keys maintained by this map * @param the type of mapped values */ -@AnnotatedFor({"nullness"}) -public @Modifiable class ConcurrentHashMap extends AbstractMap +@AnnotatedFor({"nullness", "modifiability"}) +public class ConcurrentHashMap extends AbstractMap implements ConcurrentMap, Serializable { private static final long serialVersionUID = 7249069246763182397L; @@ -848,7 +851,7 @@ static final void setTabAt(Node[] tab, int i, Node v) { /** * Creates a new, empty map with the default initial table size (16). */ - public ConcurrentHashMap() { + public @Modifiable ConcurrentHashMap() { } /** @@ -861,7 +864,7 @@ public ConcurrentHashMap() { * @throws IllegalArgumentException if the initial capacity of * elements is negative */ - public ConcurrentHashMap(int initialCapacity) { + public @Modifiable ConcurrentHashMap(int initialCapacity) { this(initialCapacity, LOAD_FACTOR, 1); } @@ -870,7 +873,7 @@ public ConcurrentHashMap(int initialCapacity) { * * @param m the map */ - public ConcurrentHashMap(Map m) { + public @Modifiable ConcurrentHashMap(Map m) { this.sizeCtl = DEFAULT_CAPACITY; putAll(m); } @@ -890,7 +893,7 @@ public ConcurrentHashMap(Map m) { * * @since 1.6 */ - public ConcurrentHashMap(int initialCapacity, float loadFactor) { + public @Modifiable ConcurrentHashMap(int initialCapacity, float loadFactor) { this(initialCapacity, loadFactor, 1); } @@ -912,7 +915,7 @@ public ConcurrentHashMap(int initialCapacity, float loadFactor) { * negative or the load factor or concurrencyLevel are * nonpositive */ - public ConcurrentHashMap(int initialCapacity, + public @Modifiable ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) throw new IllegalArgumentException(); @@ -1033,7 +1036,7 @@ public boolean containsValue(@GuardSatisfied @UnknownSignedness Object value) { * @throws NullPointerException if the specified key or value is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V put(K key, V value) { + public @Nullable V put(@Growable @Replaceable ConcurrentHashMap this, K key, V value) { return putVal(key, value, false); } @@ -1114,7 +1117,7 @@ else if (f instanceof ReservationNode) * * @param m mappings to be stored in this map */ - public void putAll(Map m) { + public void putAll(@Growable @Replaceable ConcurrentHashMap this, Map m) { tryPresize(m.size()); for (Map.Entry e : m.entrySet()) putVal(e.getKey(), e.getValue(), false); @@ -1129,7 +1132,7 @@ public void putAll(Map m) { * {@code null} if there was no mapping for {@code key} * @throws NullPointerException if the specified key is null */ - public @Nullable V remove(@GuardSatisfied @UnknownSignedness Object key) { + public @Nullable V remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key) { return replaceNode(key, null, null); } @@ -1214,7 +1217,7 @@ else if (f instanceof ReservationNode) /** * Removes all of the mappings from this map. */ - public void clear() { + public void clear(@Shrinkable ConcurrentHashMap this) { long delta = 0L; // negative number of deletions int i = 0; Node[] tab = table; @@ -1574,7 +1577,7 @@ private void readObject(java.io.ObjectInputStream s) * @throws NullPointerException if the specified key or value is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) - public @Nullable V putIfAbsent(K key, V value) { + public @Nullable V putIfAbsent(@Growable ConcurrentHashMap this, K key, V value) { return putVal(key, value, true); } @@ -1583,7 +1586,7 @@ private void readObject(java.io.ObjectInputStream s) * * @throws NullPointerException if the specified key is null */ - public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + public boolean remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) throw new NullPointerException(); return value != null && replaceNode(key, null, value) != null; @@ -1594,7 +1597,7 @@ public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatis * * @throws NullPointerException if any of the arguments are null */ - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); return replaceNode(key, newValue, oldValue) != null; @@ -1607,7 +1610,7 @@ public boolean replace(K key, V oldValue, V newValue) { * or {@code null} if there was no mapping for the key * @throws NullPointerException if the specified key or value is null */ - public @Nullable V replace(K key, V value) { + public @Nullable V replace(@Replaceable ConcurrentHashMap this, K key, V value) { if (key == null || value == null) throw new NullPointerException(); return replaceNode(key, value, null); @@ -1643,7 +1646,7 @@ public void forEach(BiConsumer action) { } } - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable ConcurrentHashMap this, BiFunction function) { if (function == null) throw new NullPointerException(); Node[] t; if ((t = table) != null) { @@ -1726,7 +1729,7 @@ boolean removeValueIf(Predicate function) { * @throws RuntimeException or Error if the mappingFunction does so, * in which case the mapping is left unestablished */ - public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { + public @PolyNull V computeIfAbsent(@Growable ConcurrentHashMap this, K key, Function mappingFunction) { if (key == null || mappingFunction == null) throw new NullPointerException(); int h = spread(key.hashCode()); @@ -1838,7 +1841,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ - public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { + public @PolyNull V computeIfPresent(@Shrinkable @Replaceable ConcurrentHashMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); int h = spread(key.hashCode()); @@ -1932,7 +1935,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ - public @PolyNull V compute(K key, + public @PolyNull V compute(@Modifiable ConcurrentHashMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); @@ -2061,7 +2064,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ - public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { + public @PolyNull V merge(@Modifiable ConcurrentHashMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) throw new NullPointerException(); int h = spread(key.hashCode()); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 062343c89d66..2e86d17af041 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -36,10 +36,14 @@ package java.util.concurrent; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; @@ -51,6 +55,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.AnnotatedFor; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -126,7 +131,8 @@ * @param the type of mapped values * @since 1.6 */ -public @Modifiable class ConcurrentSkipListMap extends AbstractMap +@AnnotatedFor({"nullness", "modifiability"}) +public class ConcurrentSkipListMap extends AbstractMap implements ConcurrentNavigableMap, Cloneable, Serializable { /* * This class implements a tree-like two-dimensionally linked skip @@ -1086,7 +1092,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * Constructs a new, empty map, sorted according to the * {@linkplain Comparable natural ordering} of the keys. */ - public ConcurrentSkipListMap() { + public @Modifiable ConcurrentSkipListMap() { this.comparator = null; } @@ -1098,7 +1104,7 @@ public ConcurrentSkipListMap() { * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ - public ConcurrentSkipListMap(Comparator comparator) { + public @Modifiable ConcurrentSkipListMap(Comparator comparator) { this.comparator = comparator; } @@ -1113,7 +1119,7 @@ public ConcurrentSkipListMap(Comparator comparator) { * @throws NullPointerException if the specified map or any of its keys * or values are null */ - public ConcurrentSkipListMap(Map m) { + public @Modifiable ConcurrentSkipListMap(Map m) { this.comparator = null; putAll(m); } @@ -1127,7 +1133,7 @@ public ConcurrentSkipListMap(Map m) { * @throws NullPointerException if the specified sorted map or any of * its keys or values are null */ - public ConcurrentSkipListMap(SortedMap m) { + public @Modifiable ConcurrentSkipListMap(SortedMap m) { this.comparator = m.comparator(); buildFromSorted(m); // initializes transients } @@ -1360,7 +1366,7 @@ public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultVa * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ - public V put(K key, V value) { + public V put(@Growable @Replaceable ConcurrentSkipListMap this, K key, V value) { if (value == null) throw new NullPointerException(); return doPut(key, value, false); @@ -1376,7 +1382,7 @@ public V put(K key, V value) { * with the keys currently in the map * @throws NullPointerException if the specified key is null */ - public V remove(@GuardSatisfied @UnknownSignedness Object key) { + public V remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key) { return doRemove(key, null); } @@ -1431,7 +1437,7 @@ public boolean isEmpty() { /** * Removes all of the mappings from this map. */ - public void clear() { + public void clear(@Shrinkable ConcurrentSkipListMap this) { Index h, r, d; Node b; VarHandle.acquireFence(); while ((h = head) != null) { @@ -1476,7 +1482,7 @@ else if ((d = h.down) != null) // remove levels * or the mappingFunction is null * @since 1.8 */ - public @PolyNull V computeIfAbsent(K key, + public @PolyNull V computeIfAbsent(@Growable ConcurrentSkipListMap this, K key, Function mappingFunction) { if (key == null || mappingFunction == null) throw new NullPointerException(); @@ -1500,7 +1506,7 @@ else if ((d = h.down) != null) // remove levels * or the remappingFunction is null * @since 1.8 */ - public @PolyNull V computeIfPresent(K key, + public @PolyNull V computeIfPresent(@Shrinkable @Replaceable ConcurrentSkipListMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); @@ -1532,7 +1538,7 @@ else if (doRemove(key, v) != null) * or the remappingFunction is null * @since 1.8 */ - public @PolyNull V compute(K key, + public @PolyNull V compute(@Modifiable ConcurrentSkipListMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); @@ -1571,7 +1577,7 @@ else if (doRemove(key, v) != null) * or the remappingFunction is null * @since 1.8 */ - public @PolyNull V merge(K key, @NonNull V value, + public @PolyNull V merge(@Modifiable ConcurrentSkipListMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) throw new NullPointerException(); @@ -1706,7 +1712,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - public ConcurrentNavigableMap descendingMap() { + public @PolyModifiable ConcurrentNavigableMap descendingMap(@PolyModifiable ConcurrentSkipListMap this) { ConcurrentNavigableMap dm; if ((dm = descendingMap) != null) return dm; return descendingMap = @@ -1810,7 +1816,7 @@ public boolean equals(@Nullable Object o) { * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ - public V putIfAbsent(K key, V value) { + public V putIfAbsent(@Growable ConcurrentSkipListMap this, K key, V value) { if (value == null) throw new NullPointerException(); return doPut(key, value, true); @@ -1823,7 +1829,7 @@ public V putIfAbsent(K key, V value) { * with the keys currently in the map * @throws NullPointerException if the specified key is null */ - public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + public boolean remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) throw new NullPointerException(); return value != null && doRemove(key, value) != null; @@ -1836,7 +1842,7 @@ public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatis * with the keys currently in the map * @throws NullPointerException if any of the arguments are null */ - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable ConcurrentSkipListMap this, K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); for (;;) { @@ -1861,7 +1867,7 @@ public boolean replace(K key, V oldValue, V newValue) { * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ - public V replace(K key, V value) { + public V replace(@Replaceable ConcurrentSkipListMap this, K key, V value) { if (key == null || value == null) throw new NullPointerException(); for (;;) { @@ -1931,7 +1937,7 @@ public V putLast(K k, V v) { * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public ConcurrentNavigableMap subMap(K fromKey, + public @PolyModifiable ConcurrentNavigableMap subMap(@PolyModifiable ConcurrentSkipListMap this, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { @@ -1947,7 +1953,7 @@ public ConcurrentNavigableMap subMap(K fromKey, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public ConcurrentNavigableMap headMap(K toKey, + public @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentSkipListMap this, K toKey, boolean inclusive) { if (toKey == null) throw new NullPointerException(); @@ -1961,7 +1967,7 @@ public ConcurrentNavigableMap headMap(K toKey, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public ConcurrentNavigableMap tailMap(K fromKey, + public @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentSkipListMap this, K fromKey, boolean inclusive) { if (fromKey == null) throw new NullPointerException(); @@ -1975,7 +1981,7 @@ public ConcurrentNavigableMap tailMap(K fromKey, * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public ConcurrentNavigableMap subMap(K fromKey, K toKey) { + public @PolyModifiable ConcurrentNavigableMap subMap(@PolyModifiable ConcurrentSkipListMap this, K fromKey, K toKey) { return subMap(fromKey, true, toKey, false); } @@ -1985,7 +1991,7 @@ public ConcurrentNavigableMap subMap(K fromKey, K toKey) { * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public ConcurrentNavigableMap headMap(K toKey) { + public @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentSkipListMap this, K toKey) { return headMap(toKey, false); } @@ -1995,7 +2001,7 @@ public ConcurrentNavigableMap headMap(K toKey) { * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - public ConcurrentNavigableMap tailMap(K fromKey) { + public @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentSkipListMap this, K fromKey) { return tailMap(fromKey, true); } @@ -2119,7 +2125,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ - public Map.@Unmodifiable Entry pollFirstEntry() { + public Map.@Unmodifiable Entry pollFirstEntry(@Shrinkable ConcurrentSkipListMap this) { return doRemoveFirstEntry(); } @@ -2129,7 +2135,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ - public Map.@Unmodifiable Entry pollLastEntry() { + public Map.@Unmodifiable Entry pollLastEntry(@Shrinkable ConcurrentSkipListMap this) { return doRemoveLastEntry(); } @@ -2704,12 +2710,12 @@ public V get(Object key) { return (!inBounds(key, m.comparator)) ? null : m.get(key); } - public V put(K key, V value) { + public V put(@Growable @Replaceable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); return m.put(key, value); } - public V remove(Object key) { + public V remove(@Shrinkable SubMap this, Object key) { return (!inBounds(key, m.comparator)) ? null : m.remove(key); } @@ -2748,7 +2754,7 @@ public boolean containsValue(@UnknownSignedness Object value) { return false; } - public void clear() { + public void clear(@Shrinkable SubMap this) { Comparator cmp = m.comparator; for (ConcurrentSkipListMap.Node n = loNode(cmp); isBeforeEnd(n, cmp); @@ -2760,21 +2766,21 @@ public void clear() { /* ---------------- ConcurrentMap API methods -------------- */ - public V putIfAbsent(K key, V value) { + public V putIfAbsent(@Growable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); return m.putIfAbsent(key, value); } - public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { + public boolean remove(@Shrinkable SubMap this, @UnknownSignedness Object key, @UnknownSignedness Object value) { return inBounds(key, m.comparator) && m.remove(key, value); } - public boolean replace(K key, V oldValue, V newValue) { + public boolean replace(@Replaceable SubMap this, K key, V oldValue, V newValue) { checkKeyBounds(key, m.comparator); return m.replace(key, oldValue, newValue); } - public V replace(K key, V value) { + public V replace(@Replaceable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); return m.replace(key, value); } @@ -2831,7 +2837,7 @@ SubMap newSubMap(K fromKey, boolean fromInclusive, } @SideEffectFree - public SubMap subMap(K fromKey, boolean fromInclusive, + public @PolyModifiable SubMap subMap(@PolyModifiable SubMap this, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { if (fromKey == null || toKey == null) throw new NullPointerException(); @@ -2839,36 +2845,36 @@ public SubMap subMap(K fromKey, boolean fromInclusive, } @SideEffectFree - public SubMap headMap(K toKey, boolean inclusive) { + public @PolyModifiable SubMap headMap(@PolyModifiable SubMap this, K toKey, boolean inclusive) { if (toKey == null) throw new NullPointerException(); return newSubMap(null, false, toKey, inclusive); } @SideEffectFree - public SubMap tailMap(K fromKey, boolean inclusive) { + public @PolyModifiable SubMap tailMap(@PolyModifiable SubMap this, K fromKey, boolean inclusive) { if (fromKey == null) throw new NullPointerException(); return newSubMap(fromKey, inclusive, null, false); } @SideEffectFree - public SubMap subMap(K fromKey, K toKey) { + public @PolyModifiable SubMap subMap(@PolyModifiable SubMap this, K fromKey, K toKey) { return subMap(fromKey, true, toKey, false); } @SideEffectFree - public SubMap headMap(K toKey) { + public @PolyModifiable SubMap headMap(@PolyModifiable SubMap this, K toKey) { return headMap(toKey, false); } @SideEffectFree - public SubMap tailMap(K fromKey) { + public @PolyModifiable SubMap tailMap(@PolyModifiable SubMap this, K fromKey) { return tailMap(fromKey, true); } @SideEffectFree - public SubMap descendingMap() { + public @PolyModifiable SubMap descendingMap(@PolyModifiable SubMap this) { return new SubMap(m, lo, loInclusive, hi, hiInclusive, !isDescending); } @@ -2923,11 +2929,11 @@ public Map.Entry lastEntry() { return isDescending ? lowestEntry() : highestEntry(); } - public Map.Entry pollFirstEntry() { + public Map.Entry pollFirstEntry(@Shrinkable SubMap this) { return isDescending ? removeHighest() : removeLowest(); } - public Map.Entry pollLastEntry() { + public Map.Entry pollLastEntry(@Shrinkable SubMap this) { return isDescending ? removeLowest() : removeHighest(); } @@ -3128,7 +3134,7 @@ public void forEach(BiConsumer action) { } } - public void replaceAll(BiFunction function) { + public void replaceAll(@Replaceable ConcurrentSkipListMap this, BiFunction function) { if (function == null) throw new NullPointerException(); Node b, n; V v; if ((b = baseHead()) != null) { From 01ff0866920121f90bae3abd866d496df3b9bea5 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 22 Mar 2026 18:10:33 -0700 Subject: [PATCH 039/119] finished annotating queue --- .../classes/java/util/AbstractQueue.java | 16 ++-- .../share/classes/java/util/ArrayDeque.java | 59 ++++++------ .../share/classes/java/util/Deque.java | 40 ++++----- .../share/classes/java/util/LinkedList.java | 58 ++++++------ .../classes/java/util/PriorityQueue.java | 35 ++++---- .../share/classes/java/util/Queue.java | 12 +-- .../util/concurrent/ArrayBlockingQueue.java | 44 ++++----- .../java/util/concurrent/BlockingDeque.java | 57 ++++++------ .../java/util/concurrent/BlockingQueue.java | 25 +++--- .../concurrent/ConcurrentLinkedDeque.java | 59 ++++++------ .../concurrent/ConcurrentLinkedQueue.java | 31 ++++--- .../java/util/concurrent/DelayQueue.java | 38 ++++---- .../util/concurrent/LinkedBlockingDeque.java | 90 ++++++++++--------- .../util/concurrent/LinkedBlockingQueue.java | 42 ++++----- .../util/concurrent/LinkedTransferQueue.java | 48 +++++----- .../concurrent/PriorityBlockingQueue.java | 46 +++++----- .../util/concurrent/SynchronousQueue.java | 38 ++++---- .../java/util/concurrent/TransferQueue.java | 11 ++- 18 files changed, 395 insertions(+), 354 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index 0de1e4b3c3eb..b1272f0d6f5a 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -37,7 +37,9 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.framework.qual.AnnotatedFor; @@ -68,15 +70,15 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"lock", "nullness"}) -public @Modifiable abstract class AbstractQueue +@AnnotatedFor({"lock", "nullness", "modifiability"}) +public abstract class AbstractQueue extends AbstractCollection implements Queue { /** * Constructor for use by subclasses. */ - protected AbstractQueue() { + protected @Modifiable AbstractQueue() { } /** @@ -100,7 +102,7 @@ protected AbstractQueue() { * prevents it from being added to this queue */ @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied AbstractQueue this, E e) { + public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { if (offer(e)) return true; else @@ -118,7 +120,7 @@ public boolean add(@GuardSatisfied AbstractQueue this, E e) { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ - public E remove(@GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { E x = poll(); if (x != null) return x; @@ -152,7 +154,7 @@ public E element(@GuardSatisfied @NonEmpty AbstractQueue this) { *

This implementation repeatedly invokes {@link #poll poll} until it * returns {@code null}. */ - public void clear(@GuardSatisfied @CanShrink AbstractQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) { while (poll() != null) ; } @@ -186,7 +188,7 @@ public void clear(@GuardSatisfied @CanShrink AbstractQueue this) { * this time due to insertion restrictions * @see #add(Object) */ - public boolean addAll(@GuardSatisfied AbstractQueue this, Collection c) { + public boolean addAll(@Growable @GuardSatisfied AbstractQueue this, Collection c) { if (c == null) throw new NullPointerException(); if (c == this) diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index af465bdb2f00..3694f82a9888 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -38,7 +38,10 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -105,8 +108,8 @@ * @param the type of elements held in this deque * @since 1.6 */ -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class ArrayDeque extends AbstractCollection +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class ArrayDeque extends AbstractCollection implements Deque, Cloneable, Serializable { /* @@ -198,7 +201,7 @@ private int newCapacity(int needed, int jump) { * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */ - public ArrayDeque() { + public @Modifiable ArrayDeque() { elements = new Object[16 + 1]; } @@ -208,7 +211,7 @@ public ArrayDeque() { * * @param numElements lower bound on initial capacity of the deque */ - public ArrayDeque(@NonNegative int numElements) { + public @Modifiable ArrayDeque(@NonNegative int numElements) { elements = new Object[(numElements < 1) ? 1 : (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : @@ -225,7 +228,7 @@ public ArrayDeque(@NonNegative int numElements) { * @param c the collection whose elements are to be placed into the deque * @throws NullPointerException if the specified collection is null */ - public @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { this(c.size()); copyElements(c); } @@ -302,7 +305,7 @@ static final E nonNullElementAt(@PolyNull @PolySigned Object[] es, int i) { * @param e the element to add * @throws NullPointerException if the specified element is null */ - public void addFirst(@GuardSatisfied ArrayDeque this, E e) { + public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); final Object[] es = elements; @@ -319,7 +322,7 @@ public void addFirst(@GuardSatisfied ArrayDeque this, E e) { * @param e the element to add * @throws NullPointerException if the specified element is null */ - public void addLast(@GuardSatisfied ArrayDeque this, E e) { + public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); final Object[] es = elements; @@ -338,7 +341,7 @@ public void addLast(@GuardSatisfied ArrayDeque this, E e) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public boolean addAll(Collection c) { + public boolean addAll(@Growable ArrayDeque this, Collection c) { final int s, needed; if ((needed = (s = size()) + c.size() + 1 - elements.length) > 0) grow(needed); @@ -357,7 +360,7 @@ private void copyElements(Collection c) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @throws NullPointerException if the specified element is null */ - public boolean offerFirst(E e) { + public boolean offerFirst(@Growable ArrayDeque this, E e) { addFirst(e); return true; } @@ -369,7 +372,7 @@ public boolean offerFirst(E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @throws NullPointerException if the specified element is null */ - public boolean offerLast(E e) { + public boolean offerLast(@Growable ArrayDeque this, E e) { addLast(e); return true; } @@ -377,7 +380,7 @@ public boolean offerLast(E e) { /** * @throws NoSuchElementException {@inheritDoc} */ - public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollFirst(); if (e == null) throw new NoSuchElementException(); @@ -387,14 +390,14 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ - public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollLast(); if (e == null) throw new NoSuchElementException(); return e; } - public @Nullable E pollFirst(@GuardSatisfied @CanShrink ArrayDeque this) { + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; final int h; E e = elementAt(es = elements, h = head); @@ -405,7 +408,7 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return e; } - public @Nullable E pollLast(@GuardSatisfied @CanShrink ArrayDeque this) { + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; final int t; E e = elementAt(es = elements, t = dec(tail, es.length)); @@ -458,7 +461,7 @@ public E getLast(@GuardSatisfied @NonEmpty ArrayDeque 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 @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = elements; for (int i = head, end = tail, to = (i <= end) ? end : es.length; @@ -486,7 +489,7 @@ public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink ArrayDeque th * @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 @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = elements; for (int i = tail, end = head, to = (i >= end) ? end : 0; @@ -514,7 +517,7 @@ public boolean removeLastOccurrence(@GuardSatisfied @CanShrink ArrayDeque thi * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied ArrayDeque this, E e) { + public boolean add(@Growable @GuardSatisfied ArrayDeque this, E e) { addLast(e); return true; } @@ -528,7 +531,7 @@ public boolean add(@GuardSatisfied ArrayDeque this, E e) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ - public boolean offer(@GuardSatisfied ArrayDeque this, E e) { + public boolean offer(@Growable @GuardSatisfied ArrayDeque this, E e) { return offerLast(e); } @@ -543,7 +546,7 @@ public boolean offer(@GuardSatisfied ArrayDeque this, E e) { * @return the head of the queue represented by this deque * @throws NoSuchElementException {@inheritDoc} */ - public E remove(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); } @@ -557,7 +560,7 @@ public E remove(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { * @return the head of the queue represented by this deque, or * {@code null} if this deque is empty */ - public @Nullable E poll(@GuardSatisfied @CanShrink ArrayDeque this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { return pollFirst(); } @@ -600,7 +603,7 @@ public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { * @param e the element to push * @throws NullPointerException if the specified element is null */ - public void push(@GuardSatisfied ArrayDeque this, E e) { + public void push(@Growable @GuardSatisfied ArrayDeque this, E e) { addFirst(e); } @@ -614,7 +617,7 @@ public void push(@GuardSatisfied ArrayDeque this, E e) { * of the stack represented by this deque) * @throws NoSuchElementException {@inheritDoc} */ - public E pop(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); } @@ -696,11 +699,11 @@ public boolean isEmpty(@GuardSatisfied ArrayDeque this) { * @return an iterator over the elements in this deque */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ArrayDeque this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ArrayDeque this) { return new DeqIterator(); } - public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty ArrayDeque this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ArrayDeque this) { return new DescendingIterator(); } @@ -929,7 +932,7 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink ArrayDeque this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink ArrayDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -945,7 +948,7 @@ public boolean removeAll(@CanShrink ArrayDeque this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -1061,7 +1064,7 @@ public boolean contains(@GuardSatisfied ArrayDeque this, @GuardSatisfied @Nul * @param o element to be removed from this deque, if present * @return {@code true} if this deque contained the specified element */ - public boolean remove(@GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -1069,7 +1072,7 @@ public boolean remove(@GuardSatisfied @CanShrink ArrayDeque this, @GuardSatis * Removes all of the elements from this deque. * The deque will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink ArrayDeque this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { circularClear(elements, head, tail); head = tail = 0; } diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 196cf0d9a010..b28d09550095 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -220,8 +220,8 @@ * @param the type of elements held in this deque */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable interface Deque extends Queue, SequencedCollection { +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, @@ -240,7 +240,7 @@ * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - void addFirst(@GuardSatisfied Deque this, E e); + void addFirst(@Growable @GuardSatisfied Deque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -262,7 +262,7 @@ * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - void addLast(@GuardSatisfied Deque this, E e); + void addLast(@Growable @GuardSatisfied Deque this, E e); /** * Inserts the specified element at the front of this deque unless it would @@ -280,7 +280,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offerFirst(E e); + boolean offerFirst(@Growable Deque this, E e); /** * Inserts the specified element at the end of this deque unless it would @@ -298,7 +298,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offerLast(E e); + boolean offerLast(@Growable Deque this, E e); /** * Retrieves and removes the first element of this deque. This method @@ -308,7 +308,7 @@ * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ - E removeFirst(@GuardSatisfied @NonEmpty @CanShrink Deque this); + E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); /** * Retrieves and removes the last element of this deque. This method @@ -318,7 +318,7 @@ * @return the tail of this deque * @throws NoSuchElementException if this deque is empty */ - E removeLast(@GuardSatisfied @NonEmpty @CanShrink Deque this); + E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); /** * Retrieves and removes the first element of this deque, @@ -326,7 +326,7 @@ * * @return the head of this deque, or {@code null} if this deque is empty */ - @Nullable E pollFirst(@GuardSatisfied @CanShrink Deque this); + @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink Deque this); /** * Retrieves and removes the last element of this deque, @@ -334,7 +334,7 @@ * * @return the tail of this deque, or {@code null} if this deque is empty */ - @Nullable E pollLast(@GuardSatisfied @CanShrink Deque this); + @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink Deque this); /** * Retrieves, but does not remove, the first element of this deque. @@ -392,7 +392,7 @@ * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ - boolean removeFirstOccurrence(@GuardSatisfied @CanShrink Deque this, Object o); + boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink Deque this, Object o); /** * Removes the last occurrence of the specified element from this deque. @@ -411,7 +411,7 @@ * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ - boolean removeLastOccurrence(@GuardSatisfied @CanShrink Deque this, Object o); + boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Deque this, Object o); // *** Queue methods *** @@ -438,7 +438,7 @@ * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - boolean add(@GuardSatisfied Deque this, E e); + boolean add(@Growable @GuardSatisfied Deque this, E e); /** * Inserts the specified element into the queue represented by this deque @@ -461,7 +461,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offer(E e); + boolean offer(@Growable Deque this, E e); /** * Retrieves and removes the head of the queue represented by this deque @@ -474,7 +474,7 @@ * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ - E remove(@GuardSatisfied @NonEmpty @CanShrink Deque this); + E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); /** * Retrieves and removes the head of the queue represented by this deque @@ -486,7 +486,7 @@ * @return the first element of this deque, or {@code null} if * this deque is empty */ - @Nullable E poll(@GuardSatisfied @CanShrink Deque this); + @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink Deque this); /** * Retrieves, but does not remove, the head of the queue represented by @@ -537,7 +537,7 @@ * @throws IllegalArgumentException if some property of an element of the * specified collection prevents it from being added to this deque */ - boolean addAll(Collection c); + boolean addAll(@Growable Deque this, Collection c); // *** Stack methods *** @@ -559,7 +559,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - void push(@GuardSatisfied Deque this, E e); + void push(@Growable @GuardSatisfied Deque this, E e); /** * Pops an element from the stack represented by this deque. In other @@ -571,7 +571,7 @@ * of the stack represented by this deque) * @throws NoSuchElementException if this deque is empty */ - E pop(@GuardSatisfied @NonEmpty @CanShrink Deque this); + E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); // *** Collection methods *** @@ -595,7 +595,7 @@ * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ - boolean remove(@GuardSatisfied @CanShrink Deque this, @UnknownSignedness Object o); + boolean remove(@Shrinkable @GuardSatisfied @CanShrink Deque this, @UnknownSignedness Object o); /** * Returns {@code true} if this deque contains the specified element. diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index c259bce02c1f..b4b11f1edf6d 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -31,7 +31,11 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -109,8 +113,8 @@ */ @CFComment({"lock/nullness: This class permits null elements"}) -@AnnotatedFor({"lock", "nullness", "index"}) -public @Modifiable class LinkedList +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) +public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable { @@ -298,7 +302,7 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { * @return the first element from this list * @throws NoSuchElementException if this list is empty */ - public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node f = first; if (f == null) throw new NoSuchElementException(); @@ -311,7 +315,7 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * @return the last element from this list * @throws NoSuchElementException if this list is empty */ - public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node l = last; if (l == null) throw new NoSuchElementException(); @@ -323,7 +327,7 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * * @param e the element to add */ - public void addFirst(@GuardSatisfied LinkedList this, E e) { + public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { linkFirst(e); } @@ -334,7 +338,7 @@ public void addFirst(@GuardSatisfied LinkedList this, E e) { * * @param e the element to add */ - public void addLast(@GuardSatisfied LinkedList this, E e) { + public void addLast(@Growable @GuardSatisfied LinkedList this, E e) { linkLast(e); } @@ -373,7 +377,7 @@ public boolean contains(@GuardSatisfied LinkedList this, @GuardSatisfied @Nul */ @ReleasesNoLocks @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied LinkedList this, E e) { + public boolean add(@Growable @GuardSatisfied LinkedList this, E e) { linkLast(e); return true; } @@ -392,7 +396,7 @@ public boolean add(@GuardSatisfied LinkedList this, E e) { * @return {@code true} if this list contained the specified element */ @ReleasesNoLocks - public boolean remove(@GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { for (Node x = first; x != null; x = x.next) { if (x.item == null) { @@ -423,7 +427,7 @@ public boolean remove(@GuardSatisfied @CanShrink LinkedList this, @GuardSatis * @return {@code true} if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */ - public boolean addAll(@GuardSatisfied LinkedList this, Collection c) { + public boolean addAll(@Growable @GuardSatisfied LinkedList this, Collection c) { return addAll(size, c); } @@ -442,7 +446,7 @@ public boolean addAll(@GuardSatisfied LinkedList this, Collection this, @NonNegative int index, Collection c) { + public boolean addAll(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, Collection c) { checkPositionIndex(index); Object[] a = c.toArray(); @@ -485,7 +489,7 @@ public boolean addAll(@GuardSatisfied LinkedList this, @NonNegative int index * Removes all of the elements from this list. * The list will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink LinkedList this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit // more than one generation @@ -527,7 +531,7 @@ public E get(@GuardSatisfied LinkedList this, @NonNegative int index) { * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(@GuardSatisfied LinkedList this, @NonNegative int index, E element) { + public E set(@Replaceable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkElementIndex(index); Node x = node(index); E oldVal = x.item; @@ -544,7 +548,7 @@ public E set(@GuardSatisfied LinkedList this, @NonNegative int index, E eleme * @param element element to be inserted * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(@GuardSatisfied LinkedList this, @NonNegative int index, E element) { + public void add(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkPositionIndex(index); if (index == size) @@ -562,7 +566,7 @@ public void add(@GuardSatisfied LinkedList this, @NonNegative int index, E el * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@GuardSatisfied @CanShrink LinkedList this, @NonNegative int index) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @NonNegative int index) { checkElementIndex(index); return unlink(node(index)); } @@ -713,7 +717,7 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { * @return the head of this list, or {@code null} if this list is empty * @since 1.5 */ - public @Nullable E poll(@GuardSatisfied @CanShrink LinkedList this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node f = first; return (f == null) ? null : unlinkFirst(f); } @@ -725,7 +729,7 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { * @throws NoSuchElementException if this list is empty * @since 1.5 */ - public E remove(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); } @@ -736,7 +740,7 @@ public E remove(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * @return {@code true} (as specified by {@link Queue#offer}) * @since 1.5 */ - public boolean offer(E e) { + public boolean offer(@Growable LinkedList this, E e) { return add(e); } @@ -748,7 +752,7 @@ public boolean offer(E e) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @since 1.6 */ - public boolean offerFirst(E e) { + public boolean offerFirst(@Growable LinkedList this, E e) { addFirst(e); return true; } @@ -760,7 +764,7 @@ public boolean offerFirst(E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @since 1.6 */ - public boolean offerLast(E e) { + public boolean offerLast(@Growable LinkedList this, E e) { addLast(e); return true; } @@ -801,7 +805,7 @@ public boolean offerLast(E e) { * this list is empty * @since 1.6 */ - public @Nullable E pollFirst(@GuardSatisfied @CanShrink LinkedList this) { + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node f = first; return (f == null) ? null : unlinkFirst(f); } @@ -814,7 +818,7 @@ public boolean offerLast(E e) { * this list is empty * @since 1.6 */ - public @Nullable E pollLast(@GuardSatisfied @CanShrink LinkedList this) { + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node l = last; return (l == null) ? null : unlinkLast(l); } @@ -828,7 +832,7 @@ public boolean offerLast(E e) { * @param e the element to push * @since 1.6 */ - public void push(@GuardSatisfied LinkedList this, E e) { + public void push(@Growable @GuardSatisfied LinkedList this, E e) { addFirst(e); } @@ -843,7 +847,7 @@ public void push(@GuardSatisfied LinkedList this, E e) { * @throws NoSuchElementException if this list is empty * @since 1.6 */ - public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); } @@ -856,7 +860,7 @@ public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * @return {@code true} if the list contained the specified element * @since 1.6 */ - public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return remove(o); } @@ -869,7 +873,7 @@ public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink LinkedList th * @return {@code true} if the list contained the specified element * @since 1.6 */ - public boolean removeLastOccurrence(@GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { for (Node x = last; x != null; x = x.prev) { if (x.item == null) { @@ -909,7 +913,7 @@ public boolean removeLastOccurrence(@GuardSatisfied @CanShrink LinkedList thi * @throws IndexOutOfBoundsException {@inheritDoc} * @see List#listIterator(int) */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty LinkedList this, @NonNegative int index) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedList this, @NonNegative int index) { checkPositionIndex(index); return new ListItr(index); } @@ -1031,7 +1035,7 @@ private static class Node { /** * @since 1.6 */ - public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty LinkedList this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedList this) { return new DescendingIterator(); } diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index c962173e0a53..b9dcca378005 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -30,7 +30,10 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -105,9 +108,9 @@ * @param the type of elements held in this queue */ @CFComment({"lock/nullness: This class doesn't permits null elements"}) -@AnnotatedFor({"lock", "nullness", "index"}) +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) @SuppressWarnings("unchecked") -public @Modifiable class PriorityQueue extends AbstractQueue +public class PriorityQueue extends AbstractQueue implements java.io.Serializable { @java.io.Serial @@ -148,7 +151,7 @@ * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. */ - public PriorityQueue() { + public @Modifiable PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -161,7 +164,7 @@ public PriorityQueue() { * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public PriorityQueue(@Positive int initialCapacity) { + public @Modifiable PriorityQueue(@Positive int initialCapacity) { this(initialCapacity, null); } @@ -174,7 +177,7 @@ public PriorityQueue(@Positive int initialCapacity) { * natural ordering} of the elements will be used. * @since 1.8 */ - public PriorityQueue(Comparator comparator) { + public @Modifiable PriorityQueue(Comparator comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); } @@ -189,7 +192,7 @@ public PriorityQueue(Comparator comparator) { * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 */ - public PriorityQueue(@Positive int initialCapacity, + public @Modifiable PriorityQueue(@Positive int initialCapacity, Comparator comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility @@ -215,7 +218,7 @@ public PriorityQueue(@Positive int initialCapacity, * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { + public @Modifiable @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { if (c instanceof SortedSet) { SortedSet ss = (SortedSet) c; this.comparator = (Comparator) ss.comparator(); @@ -246,7 +249,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified priority queue or any * of its elements are null */ - public PriorityQueue(PriorityQueue c) { + public @Modifiable PriorityQueue(PriorityQueue c) { this.comparator = (Comparator) c.comparator(); initFromPriorityQueue(c); } @@ -264,7 +267,7 @@ public PriorityQueue(PriorityQueue c) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public PriorityQueue(SortedSet c) { + public @Modifiable PriorityQueue(SortedSet c) { this.comparator = (Comparator) c.comparator(); initElementsFromCollection(c); } @@ -331,7 +334,7 @@ private void grow(int minCapacity) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(@GuardSatisfied PriorityQueue this, E e) { + public boolean add(@Growable @GuardSatisfied PriorityQueue this, E e) { return offer(e); } @@ -344,7 +347,7 @@ public boolean add(@GuardSatisfied PriorityQueue this, E e) { * according to the priority queue's ordering * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable PriorityQueue this, E e) { if (e == null) throw new NullPointerException(); modCount++; @@ -382,7 +385,7 @@ private int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @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(@GuardSatisfied @CanShrink PriorityQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink PriorityQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { int i = indexOf(o); if (i == -1) return false; @@ -494,7 +497,7 @@ public boolean contains(@GuardSatisfied PriorityQueue this, @GuardSatisfied @ * @return an iterator over the elements in this queue */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty PriorityQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty PriorityQueue this) { return new Itr(); } @@ -594,7 +597,7 @@ public void remove() { * Removes all of the elements from this priority queue. * The queue will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink PriorityQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityQueue this) { modCount++; final Object[] es = queue; for (int i = 0, n = size; i < n; i++) @@ -602,7 +605,7 @@ public void clear(@GuardSatisfied @CanShrink PriorityQueue this) { size = 0; } - public @Nullable E poll(@GuardSatisfied @CanShrink PriorityQueue this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityQueue this) { final Object[] es; final E result; @@ -925,7 +928,7 @@ public int characteristics() { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@GuardSatisfied @CanShrink PriorityQueue this, Predicate filter) { + public boolean removeIf(@Shrinkable @GuardSatisfied @CanShrink PriorityQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index aa7b3a2a2198..284ae958a655 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -149,8 +149,8 @@ * @param the type of elements held in this queue */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) -@AnnotatedFor({"lock", "nullness"}) -public @Modifiable interface Queue extends Collection { +@AnnotatedFor({"lock", "nullness", "modifiability"}) +public interface Queue extends Collection { /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning @@ -169,7 +169,7 @@ * prevents it from being added to this queue */ @EnsuresNonEmpty("this") - boolean add(@GuardSatisfied Queue this, E e); + boolean add(@Growable @GuardSatisfied Queue this, E e); /** * Inserts the specified element into this queue if it is possible to do @@ -188,7 +188,7 @@ * @throws IllegalArgumentException if some property of this element * prevents it from being added to this queue */ - boolean offer(E e); + boolean offer(@Growable Queue this, E e); /** * Retrieves and removes the head of this queue. This method differs @@ -198,7 +198,7 @@ * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ - E remove(@GuardSatisfied @NonEmpty @CanShrink Queue this); + E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Queue this); /** * Retrieves and removes the head of this queue, @@ -206,7 +206,7 @@ * * @return the head of this queue, or {@code null} if this queue is empty */ - @Nullable E poll(@GuardSatisfied @CanShrink Queue this); + @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink Queue this); /** * Retrieves, but does not remove, the head of this queue. This method 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 31dca4513aea..aaa8c668f02f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -38,8 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -101,8 +103,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) -public @Modifiable class ArrayBlockingQueue extends AbstractQueue +@AnnotatedFor({"nullness", "modifiability"}) +public class ArrayBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { /* @@ -272,7 +274,7 @@ void removeAt(final int removeIndex) { * @param capacity the capacity of this queue * @throws IllegalArgumentException if {@code capacity < 1} */ - public ArrayBlockingQueue(int capacity) { + public @Modifiable ArrayBlockingQueue(int capacity) { this(capacity, false); } @@ -286,7 +288,7 @@ public ArrayBlockingQueue(int capacity) { * if {@code false} the access order is unspecified. * @throws IllegalArgumentException if {@code capacity < 1} */ - public ArrayBlockingQueue(int capacity, boolean fair) { + public @Modifiable ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; @@ -311,7 +313,7 @@ public ArrayBlockingQueue(int capacity, boolean fair) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public ArrayBlockingQueue(int capacity, boolean fair, + public @Modifiable ArrayBlockingQueue(int capacity, boolean fair, Collection c) { this(capacity, fair); @@ -345,7 +347,7 @@ public ArrayBlockingQueue(int capacity, boolean fair, * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable ArrayBlockingQueue this, E e) { return super.add(e); } @@ -358,7 +360,7 @@ public boolean add(E e) { * * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable ArrayBlockingQueue this, E e) { Objects.requireNonNull(e); final ReentrantLock lock = this.lock; lock.lock(); @@ -381,7 +383,7 @@ public boolean offer(E e) { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public void put(E e) throws InterruptedException { + public void put(@Growable ArrayBlockingQueue this, E e) throws InterruptedException { Objects.requireNonNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -402,7 +404,7 @@ public void put(E e) throws InterruptedException { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public boolean offer(E e, long timeout, TimeUnit unit) + public boolean offer(@Growable ArrayBlockingQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { Objects.requireNonNull(e); @@ -422,7 +424,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) } } - public E poll(@GuardSatisfied @CanShrink ArrayBlockingQueue this) { + public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -432,7 +434,7 @@ public E poll(@GuardSatisfied @CanShrink ArrayBlockingQueue this) { } } - public E take(@GuardSatisfied @CanShrink ArrayBlockingQueue this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { @@ -444,7 +446,7 @@ public E take(@GuardSatisfied @CanShrink ArrayBlockingQueue this) throws Inte } } - public E poll(@GuardSatisfied @CanShrink ArrayBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -529,7 +531,7 @@ 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(@CanShrink ArrayBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink ArrayBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); @@ -680,7 +682,7 @@ public String toString() { * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink ArrayBlockingQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -719,7 +721,7 @@ private static void circularClear(Object[] items, int i, int end) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -729,7 +731,7 @@ public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growa * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -781,7 +783,7 @@ else if (i > take) * * @return an iterator over the elements in this queue in proper sequence */ - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ArrayBlockingQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ArrayBlockingQueue this) { return new Itr(); } @@ -1495,7 +1497,7 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink ArrayBlockingQueue this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink ArrayBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1503,7 +1505,7 @@ public boolean removeIf(@CanShrink ArrayBlockingQueue this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink ArrayBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1511,7 +1513,7 @@ public boolean removeAll(@CanShrink ArrayBlockingQueue this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java index 07ed526f0ef8..6003174b0c6c 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java @@ -38,7 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -210,8 +213,8 @@ * @author Doug Lea * @param the type of elements held in this deque */ -@AnnotatedFor({"nullness"}) -public @Modifiable interface BlockingDeque extends BlockingQueue, Deque { +@AnnotatedFor({"nullness", "modifiability"}) +public interface BlockingDeque extends BlockingQueue, Deque { /* * We have "diamond" multiple interface inheritance here, and that * introduces ambiguities. Methods might end up with different @@ -232,7 +235,7 @@ * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ - void addFirst(E e); + void addFirst(@Growable BlockingDeque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -247,7 +250,7 @@ * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ - void addLast(E e); + void addLast(@Growable BlockingDeque this, E e); /** * Inserts the specified element at the front of this deque if it is @@ -263,7 +266,7 @@ * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ - boolean offerFirst(E e); + boolean offerFirst(@Growable BlockingDeque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -279,7 +282,7 @@ * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ - boolean offerLast(E e); + boolean offerLast(@Growable BlockingDeque this, E e); /** * Inserts the specified element at the front of this deque, @@ -293,7 +296,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - void putFirst(E e) throws InterruptedException; + void putFirst(@Growable BlockingDeque this, E e) throws InterruptedException; /** * Inserts the specified element at the end of this deque, @@ -307,7 +310,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - void putLast(E e) throws InterruptedException; + void putLast(@Growable BlockingDeque this, E e) throws InterruptedException; /** * Inserts the specified element at the front of this deque, @@ -328,7 +331,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offerFirst(E e, long timeout, TimeUnit unit) + boolean offerFirst(@Growable BlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -350,7 +353,7 @@ boolean offerFirst(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offerLast(E e, long timeout, TimeUnit unit) + boolean offerLast(@Growable BlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -360,7 +363,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @return the head of this deque * @throws InterruptedException if interrupted while waiting */ - E takeFirst(@CanShrink BlockingDeque this) throws InterruptedException; + E takeFirst(@Shrinkable @CanShrink BlockingDeque this) throws InterruptedException; /** * Retrieves and removes the last element of this deque, waiting @@ -369,7 +372,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @return the tail of this deque * @throws InterruptedException if interrupted while waiting */ - E takeLast(@CanShrink BlockingDeque this) throws InterruptedException; + E takeLast(@Shrinkable @CanShrink BlockingDeque this) throws InterruptedException; /** * Retrieves and removes the first element of this deque, waiting @@ -384,7 +387,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ - @Nullable E pollFirst(@CanShrink BlockingDeque this, long timeout, TimeUnit unit) + @Nullable E pollFirst(@Shrinkable @CanShrink BlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -400,7 +403,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ - @Nullable E pollLast(@CanShrink BlockingDeque this, long timeout, TimeUnit unit) + @Nullable E pollLast(@Shrinkable @CanShrink BlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -419,7 +422,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ - boolean removeFirstOccurrence(@CanShrink BlockingDeque this, Object o); + boolean removeFirstOccurrence(@Shrinkable @CanShrink BlockingDeque this, Object o); /** * Removes the last occurrence of the specified element from this deque. @@ -437,7 +440,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ - boolean removeLastOccurrence(@CanShrink BlockingDeque this, Object o); + boolean removeLastOccurrence(@Shrinkable @CanShrink BlockingDeque this, Object o); // *** BlockingQueue methods *** @@ -461,7 +464,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") - boolean add(E e); + boolean add(@Growable BlockingDeque this, E e); /** * Inserts the specified element into the queue represented by this deque @@ -481,7 +484,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offer(E e); + boolean offer(@Growable BlockingDeque this, E e); /** * Inserts the specified element into the queue represented by this deque @@ -498,7 +501,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - void put(E e) throws InterruptedException; + void put(@Growable BlockingDeque this, E e) throws InterruptedException; /** * Inserts the specified element into the queue represented by this deque @@ -518,7 +521,7 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ - boolean offer(E e, long timeout, TimeUnit unit) + boolean offer(@Growable BlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -532,7 +535,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ - E remove(@GuardSatisfied @NonEmpty @CanShrink BlockingDeque this); + E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink BlockingDeque this); /** * Retrieves and removes the head of the queue represented by this deque @@ -543,7 +546,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * * @return the head of this deque, or {@code null} if this deque is empty */ - @Nullable E poll(@CanShrink BlockingDeque this); + @Nullable E poll(@Shrinkable @CanShrink BlockingDeque this); /** * Retrieves and removes the head of the queue represented by this deque @@ -555,7 +558,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of this deque * @throws InterruptedException if interrupted while waiting */ - E take(@CanShrink BlockingDeque this) throws InterruptedException; + E take(@Shrinkable @CanShrink BlockingDeque this) throws InterruptedException; /** * Retrieves and removes the head of the queue represented by this deque @@ -569,7 +572,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * specified waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ - @Nullable E poll(@CanShrink BlockingDeque this, long timeout, TimeUnit unit) + @Nullable E poll(@Shrinkable @CanShrink BlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -615,7 +618,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ - boolean remove(@CanShrink BlockingDeque this, @UnknownSignedness Object o); + boolean remove(@Shrinkable @CanShrink BlockingDeque this, @UnknownSignedness Object o); /** * Returns {@code true} if this deque contains the specified element. @@ -649,7 +652,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return an iterator over the elements in this deque in proper sequence */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty BlockingDeque this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty BlockingDeque this); // *** Stack methods *** @@ -666,5 +669,5 @@ boolean offer(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ - void push(E e); + void push(@Growable BlockingDeque this, E e); } diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index 8561dc415bf0..caaf988881c1 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -37,8 +37,9 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -189,8 +190,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) -public @Modifiable interface BlockingQueue extends Queue { +@AnnotatedFor({"nullness", "modifiability"}) +public interface BlockingQueue extends Queue { /** * Inserts the specified element into this queue if it is possible to do * so immediately without violating capacity restrictions, returning @@ -210,7 +211,7 @@ * element prevents it from being added to this queue */ @EnsuresNonEmpty("this") - boolean add(E e); + boolean add(@Growable BlockingQueue this, E e); /** * Inserts the specified element into this queue if it is possible to do @@ -229,7 +230,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ - boolean offer(E e); + boolean offer(@Growable BlockingQueue this, E e); /** * Inserts the specified element into this queue, waiting if necessary @@ -243,7 +244,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ - void put(E e) throws InterruptedException; + void put(@Growable BlockingQueue this, E e) throws InterruptedException; /** * Inserts the specified element into this queue, waiting up to the @@ -263,7 +264,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ - boolean offer(E e, long timeout, TimeUnit unit) + boolean offer(@Growable BlockingQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -273,7 +274,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of this queue * @throws InterruptedException if interrupted while waiting */ - E take() throws InterruptedException; + E take(@Shrinkable BlockingQueue this) throws InterruptedException; /** * Retrieves and removes the head of this queue, waiting up to the @@ -287,7 +288,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * specified waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ - @Nullable E poll(long timeout, TimeUnit unit) + @Nullable E poll(@Shrinkable BlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -321,7 +322,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ - boolean remove(@CanShrink BlockingQueue this, @UnknownSignedness Object o); + boolean remove(@Shrinkable @CanShrink BlockingQueue this, @UnknownSignedness Object o); /** * Returns {@code true} if this queue contains the specified element. @@ -363,7 +364,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ - int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, @Growable Collection c); + int drainTo(@Shrinkable @GuardSatisfied @CanShrink BlockingQueue this, @Growable Collection c); /** * Removes at most the given number of available elements from @@ -388,5 +389,5 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ - int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, @Growable Collection c, int maxElements); + int drainTo(@Shrinkable @GuardSatisfied @CanShrink BlockingQueue this, @Growable Collection c, int maxElements); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 9c390690cc60..3e526a303926 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -38,7 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -112,8 +115,8 @@ * @author Martin Buchholz * @param the type of elements held in this deque */ -@AnnotatedFor({"nullness"}) -public @Modifiable class ConcurrentLinkedDeque +@AnnotatedFor({"nullness", "modifiability"}) +public class ConcurrentLinkedDeque extends AbstractCollection implements Deque, java.io.Serializable { @@ -788,7 +791,7 @@ private E screenNullResult(@NonNull E v) { /** * Constructs an empty deque. */ - public ConcurrentLinkedDeque() { + public @Modifiable ConcurrentLinkedDeque() { head = tail = new Node(); } @@ -801,7 +804,7 @@ public ConcurrentLinkedDeque() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public ConcurrentLinkedDeque(Collection c) { + public @Modifiable ConcurrentLinkedDeque(Collection c) { // Copy c into a private chain of Nodes Node h = null, t = null; for (E e : c) { @@ -843,7 +846,7 @@ private void initHeadTail(Node h, Node t) { * * @throws NullPointerException if the specified element is null */ - public void addFirst(E e) { + public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { linkFirst(e); } @@ -856,7 +859,7 @@ public void addFirst(E e) { * * @throws NullPointerException if the specified element is null */ - public void addLast(E e) { + public void addLast(@Growable ConcurrentLinkedDeque this, E e) { linkLast(e); } @@ -867,7 +870,7 @@ public void addLast(E e) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @throws NullPointerException if the specified element is null */ - public boolean offerFirst(E e) { + public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { linkFirst(e); return true; } @@ -881,7 +884,7 @@ public boolean offerFirst(E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @throws NullPointerException if the specified element is null */ - public boolean offerLast(E e) { + public boolean offerLast(@Growable ConcurrentLinkedDeque this, E e) { linkLast(e); return true; } @@ -932,7 +935,7 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { return screenNullResult(peekLast()); } - public @Nullable E pollFirst(@GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { for (Node first = first(), p = first;;) { final E item; @@ -953,7 +956,7 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { } } - public @Nullable E pollLast(@GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { for (Node last = last(), p = last;;) { final E item; @@ -977,14 +980,14 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ - public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollFirst()); } /** * @throws NoSuchElementException {@inheritDoc} */ - public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollLast()); } @@ -997,7 +1000,7 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this, E e) { return offerLast(e); } @@ -1010,23 +1013,23 @@ public boolean offer(E e) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable ConcurrentLinkedDeque this, E e) { return offerLast(e); } - public @Nullable E poll(@CanShrink ConcurrentLinkedDeque this) { return pollFirst(); } + public @Nullable E poll(@Shrinkable @CanShrink ConcurrentLinkedDeque this) { return pollFirst(); } @Pure public @Nullable E peek() { return peekFirst(); } /** * @throws NoSuchElementException {@inheritDoc} */ - public E remove(@NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } + public E remove(@Shrinkable @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } /** * @throws NoSuchElementException {@inheritDoc} */ - public E pop(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } /** * @throws NoSuchElementException {@inheritDoc} @@ -1036,7 +1039,7 @@ public boolean add(E e) { /** * @throws NullPointerException {@inheritDoc} */ - public void push(E e) { addFirst(e); } + public void push(@Growable ConcurrentLinkedDeque this, E e) { addFirst(e); } /** * Removes the first occurrence of the specified element from this deque. @@ -1050,7 +1053,7 @@ public boolean add(E e) { * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ - public boolean removeFirstOccurrence(@CanShrink ConcurrentLinkedDeque this, Object o) { + public boolean removeFirstOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); for (Node p = first(); p != null; p = succ(p)) { final E item; @@ -1076,7 +1079,7 @@ public boolean removeFirstOccurrence(@CanShrink ConcurrentLinkedDeque this, O * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ - public boolean removeLastOccurrence(@CanShrink ConcurrentLinkedDeque this, Object o) { + public boolean removeLastOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); for (Node p = last(); p != null; p = pred(p)) { final E item; @@ -1168,7 +1171,7 @@ public int size() { * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ - public boolean remove(@CanShrink ConcurrentLinkedDeque this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedDeque this, @GuardSatisfied @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -1184,7 +1187,7 @@ public boolean remove(@CanShrink ConcurrentLinkedDeque this, @GuardSatisfied * of its elements are null * @throws IllegalArgumentException if the collection is this deque */ - public boolean addAll(Collection c) { + public boolean addAll(@Growable ConcurrentLinkedDeque this, Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll throw new IllegalArgumentException(); @@ -1238,7 +1241,7 @@ else if (p.prev == p) // NEXT_TERMINATOR /** * Removes all of the elements from this deque. */ - public void clear(@GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { while (pollFirst() != null) ; } @@ -1371,7 +1374,7 @@ else if (a != null && size <= a.length) { * @return an iterator over the elements in this deque in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ConcurrentLinkedDeque this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentLinkedDeque this) { return new Itr(); } @@ -1385,7 +1388,7 @@ else if (a != null && size <= a.length) { * * @return an iterator over the elements in this deque in reverse order */ - public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty ConcurrentLinkedDeque this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentLinkedDeque this) { return new DescendingItr(); } @@ -1639,7 +1642,7 @@ private void readObject(java.io.ObjectInputStream s) /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink ConcurrentLinkedDeque this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1647,7 +1650,7 @@ public boolean removeIf(@CanShrink ConcurrentLinkedDeque this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1655,7 +1658,7 @@ public boolean removeAll(@CanShrink ConcurrentLinkedDeque this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 812618038246..b24e1d8d588d 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -38,7 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -124,8 +127,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) -public @Modifiable class ConcurrentLinkedQueue extends AbstractQueue +@AnnotatedFor({"nullness", "modifiability"}) +public class ConcurrentLinkedQueue extends AbstractQueue implements Queue, java.io.Serializable { private static final long serialVersionUID = 196745693267521676L; @@ -260,7 +263,7 @@ boolean casItem(E cmp, E val) { /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public ConcurrentLinkedQueue() { + public @Modifiable ConcurrentLinkedQueue() { head = tail = new Node(); } @@ -273,7 +276,7 @@ public ConcurrentLinkedQueue() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public ConcurrentLinkedQueue(Collection c) { + public @Modifiable ConcurrentLinkedQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); @@ -299,7 +302,7 @@ public ConcurrentLinkedQueue(Collection c) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable ConcurrentLinkedQueue this, E e) { return offer(e); } @@ -371,7 +374,7 @@ private Node skipDeadNodes(Node pred, Node c, Node p, Node q) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable ConcurrentLinkedQueue this, E e) { final Node newNode = new Node(Objects.requireNonNull(e)); for (Node t = tail, p = t;;) { @@ -400,7 +403,7 @@ else if (p == q) } } - public @Nullable E poll(@GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { restartFromHead: for (;;) { for (Node h = head, p = h, q;; p = q) { final E item; @@ -544,7 +547,7 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { * @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(@CanShrink ConcurrentLinkedQueue this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedQueue this, @GuardSatisfied @UnknownSignedness Object o) { if (o == null) return false; restartFromHead: for (;;) { for (Node p = head, pred = null; p != null; ) { @@ -580,7 +583,7 @@ public boolean remove(@CanShrink ConcurrentLinkedQueue this, @GuardSatisfied * of its elements are null * @throws IllegalArgumentException if the collection is this queue */ - public boolean addAll(Collection c) { + public boolean addAll(@Growable ConcurrentLinkedQueue this, Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll throw new IllegalArgumentException(); @@ -754,7 +757,7 @@ else if (a != null && size <= a.length) { * @return an iterator over the elements in this queue in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ConcurrentLinkedQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentLinkedQueue this) { return new Itr(); } @@ -992,7 +995,7 @@ public Spliterator spliterator() { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink ConcurrentLinkedQueue this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1000,7 +1003,7 @@ public boolean removeIf(@CanShrink ConcurrentLinkedQueue this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1008,12 +1011,12 @@ public boolean removeAll(@CanShrink ConcurrentLinkedQueue this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } - public void clear(@GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { bulkRemove(e -> true); } diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 09d38a174dfd..485450ec1dee 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -35,8 +35,10 @@ package java.util.concurrent; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -115,8 +117,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) -public @Modifiable class DelayQueue extends AbstractQueue +@AnnotatedFor({"nullness", "modifiability"}) +public class DelayQueue extends AbstractQueue implements BlockingQueue { private final transient ReentrantLock lock = new ReentrantLock(); @@ -150,7 +152,7 @@ /** * Creates a new {@code DelayQueue} that is initially empty. */ - public DelayQueue() {} + public @Modifiable DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -160,7 +162,7 @@ public DelayQueue() {} * @throws NullPointerException if the specified collection or any * of its elements are null */ - public DelayQueue(Collection c) { + public @Modifiable DelayQueue(Collection c) { this.addAll(c); } @@ -172,7 +174,7 @@ public DelayQueue(Collection c) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable DelayQueue this, E e) { return offer(e); } @@ -183,7 +185,7 @@ public boolean add(E e) { * @return {@code true} * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable DelayQueue this, E e) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -205,7 +207,7 @@ public boolean offer(E e) { * @param e the element to add * @throws NullPointerException {@inheritDoc} */ - public void put(E e) { + public void put(@Growable DelayQueue this, E e) { offer(e); } @@ -219,7 +221,7 @@ public void put(E e) { * @return {@code true} * @throws NullPointerException {@inheritDoc} */ - public boolean offer(E e, long timeout, TimeUnit unit) { + public boolean offer(@Growable DelayQueue this, E e, long timeout, TimeUnit unit) { return offer(e); } @@ -231,7 +233,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) { * @return the expired head of this queue, or {@code null} if this * queue has no elements with an expired delay */ - public @Nullable E poll(@GuardSatisfied @CanShrink DelayQueue this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -252,7 +254,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) { * @return the expired head of this queue * @throws InterruptedException {@inheritDoc} */ - public E take(@GuardSatisfied @CanShrink DelayQueue this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { @@ -297,7 +299,7 @@ public E take(@GuardSatisfied @CanShrink DelayQueue this) throws InterruptedE * an expired delay becomes available * @throws InterruptedException {@inheritDoc} */ - public @Nullable E poll(@GuardSatisfied @CanShrink DelayQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -347,7 +349,7 @@ public E take(@GuardSatisfied @CanShrink DelayQueue this) throws InterruptedE * @throws NoSuchElementException if this queue has no elements with an * expired delay */ - public E remove() { + public E remove(@Shrinkable DelayQueue this) { return super.remove(); } @@ -388,7 +390,7 @@ public int size() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -398,7 +400,7 @@ public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Growable Coll * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -428,7 +430,7 @@ public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, @Growable Coll * Elements with an unexpired delay are not waited for; they are * simply discarded from the queue. */ - public void clear(@GuardSatisfied @CanShrink DelayQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -522,7 +524,7 @@ public int remainingCapacity() { * Removes a single instance of the specified element from this * queue, if it is present, whether or not it has expired. */ - public boolean remove(@CanShrink DelayQueue this, @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink DelayQueue this, @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -561,7 +563,7 @@ void removeEQ(Object o) { * @return an iterator over the elements in this queue */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty DelayQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty DelayQueue this) { return new Itr(toArray()); } 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 d640e732d39c..cd6a48a92b7a 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -38,8 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -93,8 +95,8 @@ * @author Doug Lea * @param the type of elements held in this deque */ -@AnnotatedFor({"nullness"}) -public @Modifiable class LinkedBlockingDeque +@AnnotatedFor({"nullness", "modifiability"}) +public class LinkedBlockingDeque extends AbstractQueue implements BlockingDeque, java.io.Serializable { @@ -189,7 +191,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public LinkedBlockingDeque() { + public @Modifiable LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -199,7 +201,7 @@ public LinkedBlockingDeque() { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public LinkedBlockingDeque(int capacity) { + public @Modifiable LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -214,7 +216,7 @@ public LinkedBlockingDeque(int capacity) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public LinkedBlockingDeque(Collection c) { + public @Modifiable LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } @@ -333,7 +335,7 @@ void unlink(@CanShrink LinkedBlockingDeque this, Node x) { * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ - public void addFirst(E e) { + public void addFirst(@Growable LinkedBlockingDeque this, E e) { if (!offerFirst(e)) throw new IllegalStateException("Deque full"); } @@ -342,7 +344,7 @@ public void addFirst(E e) { * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ - public void addLast(E e) { + public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!offerLast(e)) throw new IllegalStateException("Deque full"); } @@ -350,7 +352,7 @@ public void addLast(E e) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean offerFirst(E e) { + public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -365,7 +367,7 @@ public boolean offerFirst(E e) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean offerLast(E e) { + public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -381,7 +383,7 @@ public boolean offerLast(E e) { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ - public void putFirst(E e) throws InterruptedException { + public void putFirst(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -398,7 +400,7 @@ public void putFirst(E e) throws InterruptedException { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ - public void putLast(E e) throws InterruptedException { + public void putLast(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -415,7 +417,7 @@ public void putLast(E e) throws InterruptedException { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ - public boolean offerFirst(E e, long timeout, TimeUnit unit) + public boolean offerFirst(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -438,7 +440,7 @@ public boolean offerFirst(E e, long timeout, TimeUnit unit) * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ - public boolean offerLast(E e, long timeout, TimeUnit unit) + public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -460,7 +462,7 @@ public boolean offerLast(E e, long timeout, TimeUnit unit) /** * @throws NoSuchElementException {@inheritDoc} */ - public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollFirst(); if (x == null) throw new NoSuchElementException(); return x; @@ -469,13 +471,13 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque /** * @throws NoSuchElementException {@inheritDoc} */ - public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollLast(); if (x == null) throw new NoSuchElementException(); return x; } - public @Nullable E pollFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -485,7 +487,7 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque } } - public @Nullable E pollLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -495,7 +497,7 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque } } - public E takeFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { + public E takeFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -508,7 +510,7 @@ public E takeFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throw } } - public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { + public E takeLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -521,7 +523,7 @@ public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws } } - public @Nullable E pollFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -539,7 +541,7 @@ public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws } } - public @Nullable E pollLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -597,7 +599,7 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { } } - public boolean removeFirstOccurrence(@CanShrink LinkedBlockingDeque this, Object o) { + public boolean removeFirstOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); @@ -614,7 +616,7 @@ public boolean removeFirstOccurrence(@CanShrink LinkedBlockingDeque this, Obj } } - public boolean removeLastOccurrence(@CanShrink LinkedBlockingDeque this, Object o) { + public boolean removeLastOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); @@ -644,7 +646,7 @@ public boolean removeLastOccurrence(@CanShrink LinkedBlockingDeque this, Obje * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable LinkedBlockingDeque this, E e) { addLast(e); return true; } @@ -652,7 +654,7 @@ public boolean add(E e) { /** * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable LinkedBlockingDeque this, E e) { return offerLast(e); } @@ -660,7 +662,7 @@ public boolean offer(E e) { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ - public void put(E e) throws InterruptedException { + public void put(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { putLast(e); } @@ -668,7 +670,7 @@ public void put(E e) throws InterruptedException { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ - public boolean offer(E e, long timeout, TimeUnit unit) + public boolean offer(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { return offerLast(e, timeout, unit); } @@ -683,19 +685,19 @@ public boolean offer(E e, long timeout, TimeUnit unit) * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ - public E remove(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); } - public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { return pollFirst(); } - public E take(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { return takeFirst(); } - public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { return pollFirst(timeout, unit); } @@ -745,7 +747,7 @@ public int remainingCapacity() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -755,7 +757,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Grow * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -781,14 +783,14 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, @Grow * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ - public void push(E e) { + public void push(@Growable LinkedBlockingDeque this, E e) { addFirst(e); } /** * @throws NoSuchElementException {@inheritDoc} */ - public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); } @@ -808,7 +810,7 @@ public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { * @param o element to be removed from this deque, if present * @return {@code true} if this deque changed as a result of the call */ - public boolean remove(@CanShrink LinkedBlockingDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink LinkedBlockingDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -866,7 +868,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @throws IllegalStateException if this deque is full * @see #add(Object) */ - public boolean addAll(Collection c) { + public boolean addAll(@Growable LinkedBlockingDeque this, Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll throw new IllegalArgumentException(); @@ -1003,7 +1005,7 @@ public String toString() { * Atomically removes all of the elements from this deque. * The deque will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -1043,7 +1045,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this deque in proper sequence */ - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { return new Itr(); } @@ -1057,7 +1059,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this deque in reverse order */ - public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { return new DescendingItr(); } @@ -1359,7 +1361,7 @@ void forEachFrom(Consumer action, Node p) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink LinkedBlockingDeque this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1367,7 +1369,7 @@ public boolean removeIf(@CanShrink LinkedBlockingDeque this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1375,7 +1377,7 @@ public boolean removeAll(@CanShrink LinkedBlockingDeque this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, 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 82f002fa2f12..9e893c436bda 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -38,8 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -95,8 +97,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) -public @Modifiable class LinkedBlockingQueue extends AbstractQueue +@AnnotatedFor({"nullness", "modifiability"}) +public class LinkedBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = -6903933977591709194L; @@ -259,7 +261,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public LinkedBlockingQueue() { + public @Modifiable LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -270,7 +272,7 @@ public LinkedBlockingQueue() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public LinkedBlockingQueue(int capacity) { + public @Modifiable LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -286,7 +288,7 @@ public LinkedBlockingQueue(int capacity) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public LinkedBlockingQueue(Collection c) { + public @Modifiable LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility @@ -342,7 +344,7 @@ public int remainingCapacity() { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public void put(E e) throws InterruptedException { + public void put(@Growable LinkedBlockingQueue this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); final int c; final Node node = new Node(e); @@ -381,7 +383,7 @@ public void put(E e) throws InterruptedException { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public boolean offer(E e, long timeout, TimeUnit unit) + public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); @@ -419,7 +421,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) * * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable LinkedBlockingQueue this, E e) { if (e == null) throw new NullPointerException(); final AtomicInteger count = this.count; if (count.get() == capacity) @@ -443,7 +445,7 @@ public boolean offer(E e) { return true; } - public E take(@GuardSatisfied @CanShrink LinkedBlockingQueue this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) throws InterruptedException { final E x; final int c; final AtomicInteger count = this.count; @@ -465,7 +467,7 @@ public E take(@GuardSatisfied @CanShrink LinkedBlockingQueue this) throws Int return x; } - public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { final E x; final int c; long nanos = unit.toNanos(timeout); @@ -490,7 +492,7 @@ public E take(@GuardSatisfied @CanShrink LinkedBlockingQueue this) throws Int return x; } - public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { final AtomicInteger count = this.count; if (count.get() == 0) return null; @@ -554,7 +556,7 @@ 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(@CanShrink LinkedBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink LinkedBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; fullyLock(); try { @@ -685,7 +687,7 @@ public String toString() { * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { fullyLock(); try { for (Node p, h = head; (p = h.next) != null; h = p) { @@ -707,7 +709,7 @@ public void clear(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -717,7 +719,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Grow * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -777,7 +779,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this queue in proper sequence */ - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty LinkedBlockingQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedBlockingQueue this) { return new Itr(); } @@ -1042,7 +1044,7 @@ void forEachFrom(Consumer action, Node p) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink LinkedBlockingQueue this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1050,7 +1052,7 @@ public boolean removeIf(@CanShrink LinkedBlockingQueue this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1058,7 +1060,7 @@ public boolean removeAll(@CanShrink LinkedBlockingQueue this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 88f512bfbaac..155309aa74a8 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -38,8 +38,11 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -105,7 +108,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -public @Modifiable class LinkedTransferQueue extends AbstractQueue +@AnnotatedFor({"nullness", "modifiability"}) +public class LinkedTransferQueue extends AbstractQueue implements TransferQueue, java.io.Serializable { private static final long serialVersionUID = -3223113410248163686L; @@ -1170,7 +1174,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public LinkedTransferQueue() { + public @Modifiable LinkedTransferQueue() { head = tail = new Node(); } @@ -1183,7 +1187,7 @@ public LinkedTransferQueue() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public LinkedTransferQueue(Collection c) { + public @Modifiable LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); @@ -1204,7 +1208,7 @@ public LinkedTransferQueue(Collection c) { * * @throws NullPointerException if the specified element is null */ - public void put(E e) { + public void put(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); } @@ -1217,7 +1221,7 @@ public void put(E e) { * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer}) * @throws NullPointerException if the specified element is null */ - public boolean offer(E e, long timeout, TimeUnit unit) { + public boolean offer(@Growable LinkedTransferQueue this, E e, long timeout, TimeUnit unit) { xfer(e, true, ASYNC, 0L); return true; } @@ -1229,7 +1233,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); return true; } @@ -1243,7 +1247,7 @@ public boolean offer(E e) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); return true; } @@ -1258,7 +1262,7 @@ public boolean add(E e) { * * @throws NullPointerException if the specified element is null */ - public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { + public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { return xfer(e, true, NOW, 0L) == null; } @@ -1273,7 +1277,7 @@ public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue thi * * @throws NullPointerException if the specified element is null */ - public void transfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { + public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { if (xfer(e, true, SYNC, 0L) != null) { Thread.interrupted(); // failure possible only due to interrupt throw new InterruptedException(); @@ -1294,7 +1298,7 @@ public void transfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e * * @throws NullPointerException if the specified element is null */ - public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e, long timeout, TimeUnit unit) + public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null) return true; @@ -1303,7 +1307,7 @@ public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue thi throw new InterruptedException(); } - public E take(@GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { E e = xfer(null, false, SYNC, 0L); if (e != null) return e; @@ -1311,14 +1315,14 @@ public E take(@GuardSatisfied @CanShrink LinkedTransferQueue this) throws Int throw new InterruptedException(); } - public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = xfer(null, false, TIMED, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) return e; throw new InterruptedException(); } - public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this) { + public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { return xfer(null, false, NOW, 0L); } @@ -1326,7 +1330,7 @@ public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1340,7 +1344,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, @Grow * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1359,7 +1363,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, @Grow * * @return an iterator over the elements in this queue in proper sequence */ - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty LinkedTransferQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedTransferQueue this) { return new Itr(); } @@ -1443,7 +1447,7 @@ public int getWaitingConsumerCount() { * @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(@CanShrink LinkedTransferQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink LinkedTransferQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; restartFromHead: for (;;) { for (Node p = head, pred = null; p != null; ) { @@ -1563,7 +1567,7 @@ private void readObject(java.io.ObjectInputStream s) /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink LinkedTransferQueue this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink LinkedTransferQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1571,7 +1575,7 @@ public boolean removeIf(@CanShrink LinkedTransferQueue this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1579,12 +1583,12 @@ public boolean removeAll(@CanShrink LinkedTransferQueue this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } - public void clear(@GuardSatisfied @CanShrink LinkedTransferQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { bulkRemove(e -> true); } 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 63083ab15d7a..e222ab85608a 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -38,8 +38,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -129,9 +131,9 @@ * @author Doug Lea * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) +@AnnotatedFor({"nullness", "modifiability"}) @SuppressWarnings("unchecked") -public @Modifiable class PriorityBlockingQueue extends AbstractQueue +public class PriorityBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = 5595510919245408276L; @@ -205,7 +207,7 @@ * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public PriorityBlockingQueue() { + public @Modifiable PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -218,7 +220,7 @@ public PriorityBlockingQueue() { * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public PriorityBlockingQueue(int initialCapacity) { + public @Modifiable PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -234,7 +236,7 @@ public PriorityBlockingQueue(int initialCapacity) { * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public PriorityBlockingQueue(int initialCapacity, + public @Modifiable PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -258,7 +260,7 @@ public PriorityBlockingQueue(int initialCapacity, * @throws NullPointerException if the specified collection or any * of its elements are null */ - public PriorityBlockingQueue(Collection c) { + public @Modifiable PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { @@ -465,7 +467,7 @@ private void heapify() { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable PriorityBlockingQueue this, E e) { return offer(e); } @@ -480,7 +482,7 @@ public boolean add(E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable PriorityBlockingQueue this, E e) { if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; @@ -513,7 +515,7 @@ public boolean offer(E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ - public void put(E e) { + public void put(@Growable PriorityBlockingQueue this, E e) { offer(e); // never need to block } @@ -532,11 +534,11 @@ public void put(E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ - public boolean offer(E e, long timeout, TimeUnit unit) { + public boolean offer(@Growable PriorityBlockingQueue this, E e, long timeout, TimeUnit unit) { return offer(e); // never need to block } - public @Nullable E poll(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -546,7 +548,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) { } } - public E take(@GuardSatisfied @CanShrink PriorityBlockingQueue this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); E result; @@ -559,7 +561,7 @@ public E take(@GuardSatisfied @CanShrink PriorityBlockingQueue this) throws I return result; } - public @Nullable E poll(@GuardSatisfied @CanShrink PriorityBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -664,7 +666,7 @@ 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(@CanShrink PriorityBlockingQueue this, @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink PriorityBlockingQueue this, @Nullable @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -729,7 +731,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -739,7 +741,7 @@ public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Gr * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -763,7 +765,7 @@ public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, @Gr * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -861,7 +863,7 @@ public void clear(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { * * @return an iterator over the elements in this queue */ - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty PriorityBlockingQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty PriorityBlockingQueue this) { return new Itr(toArray()); } @@ -1035,7 +1037,7 @@ public Spliterator spliterator() { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink PriorityBlockingQueue this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink PriorityBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1043,7 +1045,7 @@ public boolean removeIf(@CanShrink PriorityBlockingQueue this, Predicate this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink PriorityBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1051,7 +1053,7 @@ public boolean removeAll(@CanShrink PriorityBlockingQueue this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 236aea0d1ffd..fb83b03584e7 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -39,8 +39,10 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.NonNull; @@ -103,8 +105,8 @@ * @author Doug Lea and Bill Scherer and Michael Scott * @param the type of elements held in this queue */ -@AnnotatedFor({"nullness"}) -public @Modifiable class SynchronousQueue extends AbstractQueue +@AnnotatedFor({"nullness", "modifiability"}) +public class SynchronousQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = -3223113410248163686L; @@ -830,7 +832,7 @@ void clean(QNode pred, QNode s) { /** * Creates a {@code SynchronousQueue} with nonfair access policy. */ - public SynchronousQueue() { + public @Modifiable SynchronousQueue() { this(false); } @@ -840,7 +842,7 @@ public SynchronousQueue() { * @param fair if true, waiting threads contend in FIFO order for * access; otherwise the order is unspecified. */ - public SynchronousQueue(boolean fair) { + public @Modifiable SynchronousQueue(boolean fair) { transferer = fair ? new TransferQueue() : new TransferStack(); } @@ -851,7 +853,7 @@ public SynchronousQueue(boolean fair) { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public void put(E e) throws InterruptedException { + public void put(@Growable SynchronousQueue this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); if (transferer.transfer(e, false, 0) == null) { Thread.interrupted(); @@ -868,7 +870,7 @@ public void put(E e) throws InterruptedException { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - public boolean offer(E e, long timeout, TimeUnit unit) + public boolean offer(@Growable SynchronousQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); if (transferer.transfer(e, true, unit.toNanos(timeout)) != null) @@ -887,7 +889,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) * {@code false} * @throws NullPointerException if the specified element is null */ - public boolean offer(E e) { + public boolean offer(@Growable SynchronousQueue this, E e) { if (e == null) throw new NullPointerException(); return transferer.transfer(e, true, 0) != null; } @@ -899,7 +901,7 @@ public boolean offer(E e) { * @return the head of this queue * @throws InterruptedException {@inheritDoc} */ - public E take(@GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { + public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { E e = transferer.transfer(null, false, 0); if (e != null) return e; @@ -916,7 +918,7 @@ public E take(@GuardSatisfied @CanShrink SynchronousQueue this) throws Interr * specified waiting time elapses before an element is present * @throws InterruptedException {@inheritDoc} */ - public E poll(@GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = transferer.transfer(null, true, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) return e; @@ -930,7 +932,7 @@ public E poll(@GuardSatisfied @CanShrink SynchronousQueue this, long timeout, * @return the head of this queue, or {@code null} if no * element is available */ - public E poll(@GuardSatisfied @CanShrink SynchronousQueue this) { + public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { return transferer.transfer(null, true, 0); } @@ -971,7 +973,7 @@ public int remainingCapacity() { * Does nothing. * A {@code SynchronousQueue} has no internal capacity. */ - public void clear(@GuardSatisfied @CanShrink SynchronousQueue this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { } /** @@ -994,7 +996,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @param o the element to remove * @return {@code false} */ - public boolean remove(@CanShrink SynchronousQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink SynchronousQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return false; } @@ -1017,7 +1019,7 @@ public boolean containsAll(Collection c) { * @param c the collection * @return {@code false} */ - public boolean removeAll(@CanShrink SynchronousQueue this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink SynchronousQueue this, Collection c) { return false; } @@ -1028,7 +1030,7 @@ public boolean removeAll(@CanShrink SynchronousQueue this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, Collection c) { return false; } @@ -1051,7 +1053,7 @@ public E peek() { * @return an empty iterator */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty SynchronousQueue this) { + public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty SynchronousQueue this) { return Collections.emptyIterator(); } @@ -1105,7 +1107,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1121,7 +1123,7 @@ public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Growabl * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/concurrent/TransferQueue.java b/src/java.base/share/classes/java/util/concurrent/TransferQueue.java index 847c1a0bb73d..44db151f8bc9 100644 --- a/src/java.base/share/classes/java/util/concurrent/TransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/TransferQueue.java @@ -35,7 +35,9 @@ package java.util.concurrent; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.framework.qual.AnnotatedFor; /** * A {@link BlockingQueue} in which producers may wait for consumers @@ -67,7 +69,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -public @Modifiable interface TransferQueue extends BlockingQueue { +@AnnotatedFor({"nullness", "modifiability"}) +public interface TransferQueue extends BlockingQueue { /** * Transfers the element to a waiting consumer immediately, if possible. * @@ -85,7 +88,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ - boolean tryTransfer(E e); + boolean tryTransfer(@Growable TransferQueue this, E e); /** * Transfers the element to a consumer, waiting if necessary to do so. @@ -104,7 +107,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ - void transfer(E e) throws InterruptedException; + void transfer(@Growable TransferQueue this, E e) throws InterruptedException; /** * Transfers the element to a consumer if it is possible to do so @@ -133,7 +136,7 @@ * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ - boolean tryTransfer(E e, long timeout, TimeUnit unit) + boolean tryTransfer(@Growable TransferQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** From 0f42bb1997507005cdb8003f980f8a40bdc1da87 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 22 Mar 2026 22:38:12 -0700 Subject: [PATCH 040/119] annotated last two files. --- .../util/concurrent/CopyOnWriteArrayList.java | 56 ++++++++++--------- .../util/concurrent/CopyOnWriteArraySet.java | 24 ++++---- 2 files changed, 45 insertions(+), 35 deletions(-) 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 675648288395..137c3083f196 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -37,7 +37,11 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -52,6 +56,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.AnnotatedFor; import java.lang.invoke.VarHandle; import java.lang.reflect.Field; @@ -115,7 +120,8 @@ * @author Doug Lea * @param the type of elements held in this list */ -public @Modifiable class CopyOnWriteArrayList +@AnnotatedFor("modifiability") +public class CopyOnWriteArrayList implements List, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8673264195747942595L; @@ -146,7 +152,7 @@ final void setArray(Object[] a) { /** * Creates an empty list. */ - public CopyOnWriteArrayList() { + public @Modifiable CopyOnWriteArrayList() { setArray(new Object[0]); } @@ -158,7 +164,7 @@ public CopyOnWriteArrayList() { * @param c the collection of initially held elements * @throws NullPointerException if the specified collection is null */ - public CopyOnWriteArrayList(Collection c) { + public @Modifiable CopyOnWriteArrayList(Collection c) { Object[] es; if (c.getClass() == CopyOnWriteArrayList.class) es = ((CopyOnWriteArrayList)c).getArray(); @@ -177,7 +183,7 @@ public CopyOnWriteArrayList(Collection c) { * internal array) * @throws NullPointerException if the specified array is null */ - public CopyOnWriteArrayList(E[] toCopyIn) { + public @Modifiable CopyOnWriteArrayList(E[] toCopyIn) { setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class)); } @@ -461,7 +467,7 @@ public E getLast() { * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(int index, E element) { + public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { Object[] es = getArray(); E oldValue = elementAt(es, index); @@ -483,7 +489,7 @@ public E set(int index, E element) { * @return {@code true} (as specified by {@link Collection#add}) */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -501,7 +507,7 @@ public boolean add(E e) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(int index, E element) { + public void add(@Growable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -527,7 +533,7 @@ public void add(int index, E element) { * * @since 21 */ - public void addFirst(E e) { + public void addFirst(@Growable CopyOnWriteArrayList this, E e) { add(0, e); } @@ -536,7 +542,7 @@ public void addFirst(E e) { * * @since 21 */ - public void addLast(E e) { + public void addLast(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { add(getArray().length, e); } @@ -549,7 +555,7 @@ public void addLast(E e) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -575,7 +581,7 @@ public E remove(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int ind * @throws NoSuchElementException {@inheritDoc} * @since 21 */ - public E removeFirst() { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { if (getArray().length == 0) throw new NoSuchElementException(); @@ -590,7 +596,7 @@ public E removeFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ - public E removeLast() { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { int size = getArray().length; if (size == 0) @@ -612,7 +618,7 @@ public E removeLast() { * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ - public boolean remove(@CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable @CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] snapshot = getArray(); int index = indexOfRange(o, snapshot, 0, snapshot.length); return index >= 0 && remove(o, snapshot, index); @@ -692,7 +698,7 @@ void removeRange(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int fr * @param e element to be added to this list, if absent * @return {@code true} if the element was added */ - public boolean addIfAbsent(E e) { + public boolean addIfAbsent(@Growable CopyOnWriteArrayList this, E e) { Object[] snapshot = getArray(); return indexOfRange(e, snapshot, 0, snapshot.length) < 0 && addIfAbsent(e, snapshot); @@ -760,7 +766,7 @@ public boolean containsAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ - public boolean removeAll(@CanShrink CopyOnWriteArrayList this, Collection c) { + public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -781,7 +787,7 @@ public boolean removeAll(@CanShrink CopyOnWriteArrayList this, Collection this, Collection c) { + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -797,7 +803,7 @@ public boolean retainAll(@GuardSatisfied @CanShrink CopyOnWriteArrayList this * @throws NullPointerException if the specified collection is null * @see #addIfAbsent(Object) */ - public int addAllAbsent(Collection c) { + public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = c.toArray(); if (c.getClass() != ArrayList.class) { cs = cs.clone(); @@ -828,7 +834,7 @@ public int addAllAbsent(Collection c) { * Removes all of the elements from this list. * The list will be empty after this call returns. */ - public void clear(@GuardSatisfied @CanShrink CopyOnWriteArrayList this) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { setArray(new Object[0]); } @@ -844,7 +850,7 @@ public void clear(@GuardSatisfied @CanShrink CopyOnWriteArrayList this) { * @throws NullPointerException if the specified collection is null * @see #add(Object) */ - public boolean addAll(Collection c) { + public boolean addAll(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? ((CopyOnWriteArrayList)c).getArray() : c.toArray(); if (cs.length == 0) @@ -881,7 +887,7 @@ public boolean addAll(Collection c) { * @throws NullPointerException if the specified collection is null * @see #add(int,Object) */ - public boolean addAll(int index, Collection c) { + public boolean addAll(@Growable CopyOnWriteArrayList this, int index, Collection c) { Object[] cs = c.toArray(); synchronized (lock) { Object[] es = getArray(); @@ -921,7 +927,7 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(@CanShrink CopyOnWriteArrayList this, Predicate filter) { + public boolean removeIf(@Shrinkable @CanShrink CopyOnWriteArrayList this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -978,7 +984,7 @@ boolean bulkRemove(Predicate filter, int i, int end) { } } - public void replaceAll(UnaryOperator operator) { + public void replaceAll(@Replaceable CopyOnWriteArrayList this, UnaryOperator operator) { synchronized (lock) { replaceAllRange(operator, 0, getArray().length); } @@ -993,7 +999,7 @@ void replaceAllRange(UnaryOperator operator, int i, int end) { setArray(es); } - public void sort(Comparator c) { + public void sort(@Replaceable CopyOnWriteArrayList this, Comparator c) { synchronized (lock) { sortRange(c, 0, getArray().length); } @@ -1287,7 +1293,7 @@ public void forEachRemaining(Consumer action) { * @return a view of the specified range within this list * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink List subList(@PolyGrowShrink CopyOnWriteArrayList this, int fromIndex, int toIndex) { + public @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @PolyGrowShrink CopyOnWriteArrayList this, int fromIndex, int toIndex) { synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -1777,7 +1783,7 @@ public void forEachRemaining(Consumer action) { * * @since 21 */ - public List reversed() { + public @PolyModifiable @PolyGrowShrink List reversed(@PolyModifiable @PolyGrowShrink CopyOnWriteArrayList this) { return new Reversed<>(this, lock); } 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 1a9ff75c0c03..f2a816bad2c0 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -37,7 +37,9 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -51,6 +53,7 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; 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; @@ -112,7 +115,8 @@ * @author Doug Lea * @param the type of elements held in this set */ -public @Modifiable class CopyOnWriteArraySet extends AbstractSet +@AnnotatedFor({"nullness", "modifiability"}) +public class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable { private static final long serialVersionUID = 5457747651344034263L; @@ -121,7 +125,7 @@ /** * Creates an empty set. */ - public CopyOnWriteArraySet() { + public @Modifiable CopyOnWriteArraySet() { al = new CopyOnWriteArrayList(); } @@ -132,7 +136,7 @@ public CopyOnWriteArraySet() { * @param c the collection of elements to initially contain * @throws NullPointerException if the specified collection is null */ - public CopyOnWriteArraySet(Collection c) { + public @Modifiable CopyOnWriteArraySet(Collection c) { if (c.getClass() == CopyOnWriteArraySet.class) { @SuppressWarnings("unchecked") CopyOnWriteArraySet cc = (CopyOnWriteArraySet)c; @@ -248,7 +252,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * Removes all of the elements from this set. * The set will be empty after this call returns. */ - public void clear() { + public void clear(@Shrinkable CopyOnWriteArraySet this) { al.clear(); } @@ -263,7 +267,7 @@ public void clear() { * @param o object to be removed from this set, if present * @return {@code true} if this set contained the specified element */ - public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object o) { + public boolean remove(@Shrinkable CopyOnWriteArraySet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return al.remove(o); } @@ -280,7 +284,7 @@ public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * element */ @EnsuresNonEmpty("this") - public boolean add(E e) { + public boolean add(@Growable CopyOnWriteArraySet this, E e) { return al.addIfAbsent(e); } @@ -350,7 +354,7 @@ private static int compareSets(Object[] snapshot, Set set) { * @throws NullPointerException if the specified collection is null * @see #add(Object) */ - public boolean addAll(Collection c) { + public boolean addAll(@Growable CopyOnWriteArraySet this, Collection c) { return al.addAllAbsent(c) > 0; } @@ -371,7 +375,7 @@ public boolean addAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ - public boolean removeAll(Collection c) { + public boolean removeAll(@Shrinkable CopyOnWriteArraySet this, Collection c) { return al.removeAll(c); } @@ -394,7 +398,7 @@ public boolean removeAll(Collection c) { + public boolean retainAll(@Shrinkable CopyOnWriteArraySet this, Collection c) { return al.retainAll(c); } @@ -440,7 +444,7 @@ public boolean equals(@Nullable Object o) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeIf(Predicate filter) { + public boolean removeIf(@Shrinkable CopyOnWriteArraySet this, Predicate filter) { return al.removeIf(filter); } From d57124332abb37ca60b31d940ebe6f9eef45dd84 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Tue, 7 Apr 2026 23:08:25 -0700 Subject: [PATCH 041/119] for modifiable collection, annotated clone to return modifiable object; annotated EnumSet.java --- .../share/classes/java/util/ArrayDeque.java | 2 +- .../share/classes/java/util/ArrayList.java | 2 +- .../share/classes/java/util/EnumMap.java | 2 +- .../share/classes/java/util/EnumSet.java | 39 ++++++++++--------- .../share/classes/java/util/HashMap.java | 2 +- .../share/classes/java/util/HashSet.java | 2 +- .../share/classes/java/util/Hashtable.java | 2 +- .../classes/java/util/IdentityHashMap.java | 2 +- .../share/classes/java/util/LinkedList.java | 2 +- .../share/classes/java/util/TreeMap.java | 2 +- .../share/classes/java/util/TreeSet.java | 2 +- .../share/classes/java/util/Vector.java | 2 +- .../concurrent/ConcurrentSkipListMap.java | 2 +- .../concurrent/ConcurrentSkipListSet.java | 2 +- .../util/concurrent/CopyOnWriteArrayList.java | 2 +- 15 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 3694f82a9888..6e449bd96484 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -1187,7 +1187,7 @@ private T[] toArray(Class klazz) { * @return a copy of this deque */ @SideEffectFree - public ArrayDeque clone(@GuardSatisfied ArrayDeque this) { + public @Modifiable ArrayDeque clone(@GuardSatisfied ArrayDeque this) { try { @SuppressWarnings("unchecked") ArrayDeque result = (ArrayDeque) super.clone(); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 95dde7c1a067..14d142ece091 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -377,7 +377,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public Object clone(@GuardSatisfied ArrayList this) { + public @Modifiable Object clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 1c90d30c7876..b02d5e6e6c13 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -792,7 +792,7 @@ private int entryHashCode(int index) { * @return a shallow copy of this enum map */ @SuppressWarnings("unchecked") - public EnumMap clone() { + public @Modifiable EnumMap clone() { EnumMap result = null; try { result = (EnumMap) super.clone(); diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index 9a64d87cbe7f..bb0d6f2085f2 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -25,6 +25,9 @@ package java.util; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.AnnotatedFor; @@ -81,7 +84,7 @@ * @since 1.5 * @see EnumMap */ -@AnnotatedFor({"nullness", "index"}) +@AnnotatedFor({"nullness", "index", "modifiability"}) public abstract sealed class EnumSet> extends AbstractSet implements Cloneable, java.io.Serializable permits JumboEnumSet, RegularEnumSet { @@ -99,7 +102,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ final transient Enum[] universe; - EnumSet(ClasselementType, Enum[] universe) { + @Modifiable EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } @@ -113,7 +116,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An empty enum set of the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > EnumSet noneOf(Class elementType) { + public static > @Modifiable EnumSet noneOf(Class elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); @@ -134,7 +137,7 @@ public static > EnumSet noneOf(Class elementType) { * @return An enum set containing all the elements in the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > EnumSet allOf(Class elementType) { + public static > @Modifiable EnumSet allOf(Class elementType) { EnumSet result = noneOf(elementType); result.addAll(); return result; @@ -144,7 +147,7 @@ public static > EnumSet allOf(Class elementType) { * Adds all of the elements from the appropriate enum type to this enum * set, which is empty prior to the call. */ - abstract void addAll(); + abstract void addAll(@Growable EnumSet this); /** * Creates an enum set with the same element type as the specified enum @@ -155,7 +158,7 @@ public static > EnumSet allOf(Class elementType) { * @return A copy of the specified enum set. * @throws NullPointerException if {@code s} is null */ - public static > EnumSet copyOf(EnumSet s) { + public static > @Modifiable EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -173,7 +176,7 @@ public static > EnumSet copyOf(EnumSet s) { * {@code EnumSet} instance and contains no elements * @throws NullPointerException if {@code c} is null */ - public static > EnumSet copyOf(Collection c) { + public static > @Modifiable EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); } else { @@ -198,7 +201,7 @@ public static > EnumSet copyOf(Collection c) { * @return The complement of the specified set in this set * @throws NullPointerException if {@code s} is null */ - public static > EnumSet complementOf(EnumSet s) { + public static > @Modifiable EnumSet complementOf(EnumSet s) { EnumSet result = copyOf(s); result.complement(); return result; @@ -218,7 +221,7 @@ public static > EnumSet complementOf(EnumSet s) { * @throws NullPointerException if {@code e} is null * @return an enum set initially containing the specified element */ - public static > EnumSet of(E e) { + public static > @Modifiable EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); return result; @@ -239,7 +242,7 @@ public static > EnumSet of(E e) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > EnumSet of(E e1, E e2) { + public static > @Modifiable EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -262,7 +265,7 @@ public static > EnumSet of(E e1, E e2) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > EnumSet of(E e1, E e2, E e3) { + public static > @Modifiable EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -287,7 +290,7 @@ public static > EnumSet of(E e1, E e2, E e3) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > EnumSet of(E e1, E e2, E e3, E e4) { + public static > @Modifiable EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -314,7 +317,7 @@ public static > EnumSet of(E e1, E e2, E e3, E e4) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > EnumSet of(E e1, E e2, E e3, E e4, + public static > @Modifiable EnumSet of(E e1, E e2, E e3, E e4, E e5) { EnumSet result = noneOf(e1.getDeclaringClass()); @@ -341,7 +344,7 @@ public static > EnumSet of(E e1, E e2, E e3, E e4, * @return an enum set initially containing the specified elements */ @SafeVarargs - public static > EnumSet of(E first, E... rest) { + public static > @Modifiable EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) @@ -363,7 +366,7 @@ public static > EnumSet of(E first, E... rest) { * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ - public static > EnumSet range(E from, E to) { + public static > @Modifiable EnumSet range(E from, E to) { if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to); EnumSet result = noneOf(from.getDeclaringClass()); @@ -375,7 +378,7 @@ public static > EnumSet range(E from, E to) { * Adds the specified range to this enum set, which is empty prior * to the call. */ - abstract void addRange(E from, E to); + abstract void addRange(@Growable EnumSet this, E from, E to); /** * Returns a copy of this set. @@ -383,7 +386,7 @@ public static > EnumSet range(E from, E to) { * @return a copy of this set */ @SuppressWarnings("unchecked") - public EnumSet clone() { + public @Modifiable EnumSet clone() { try { return (EnumSet) super.clone(); } catch(CloneNotSupportedException e) { @@ -394,7 +397,7 @@ public EnumSet clone() { /** * Complements the contents of this enum set. */ - abstract void complement(); + abstract void complement(@Growable @Shrinkable EnumSet this); /** * Throws an exception if e is not of the correct type for this enum set. diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 1de279204ced..103af8a27a01 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -1518,7 +1518,7 @@ public void replaceAll(@Replaceable HashMap this, BiFunction this) { + public @Modifiable Object clone(@GuardSatisfied HashMap this) { HashMap result; try { result = (HashMap)super.clone(); diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 9069c6bf4c4f..f083d281b427 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -294,7 +294,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) { */ @SideEffectFree @SuppressWarnings("unchecked") - public Object clone(@GuardSatisfied HashSet this) { + public @Modifiable Object clone(@GuardSatisfied HashSet this) { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 9f8470fafb3f..aecededa6607 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -595,7 +595,7 @@ public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) * @return a clone of the hashtable */ @SideEffectFree - public synchronized Object clone(@GuardSatisfied Hashtable this) { + public synchronized @Modifiable Object clone(@GuardSatisfied Hashtable this) { Hashtable t = cloneHashtable(); t.table = new Entry[table.length]; for (int i = table.length ; i-- > 0 ; ) { diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index ccd323ff0e9c..1a48ce607ba1 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -755,7 +755,7 @@ public int hashCode(@GuardSatisfied IdentityHashMap this) { * @return a shallow copy of this map */ @SideEffectFree - public Object clone(@GuardSatisfied IdentityHashMap this) { + public @Modifiable Object clone(@GuardSatisfied IdentityHashMap this) { try { IdentityHashMap m = (IdentityHashMap) super.clone(); m.entrySet = null; diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index b4b11f1edf6d..cd3cfcc83dfe 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -1074,7 +1074,7 @@ private LinkedList superClone() { * @return a shallow copy of this {@code LinkedList} instance */ @SideEffectFree - public Object clone(@GuardSatisfied LinkedList this) { + public @Modifiable Object clone(@GuardSatisfied LinkedList this) { LinkedList clone = superClone(); // Put clone into "virgin" state diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 310920f61f3c..bea1bdc2742a 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -972,7 +972,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * * @return a shallow copy of this map */ - public Object clone(@GuardSatisfied TreeMap this) { + public @Modifiable Object clone(@GuardSatisfied TreeMap this) { TreeMap clone; try { clone = (TreeMap) super.clone(); diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 1c964058b6d3..2b55d0553f94 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -539,7 +539,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public Object clone(@GuardSatisfied TreeSet this) { + public @Modifiable Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 49b80371f705..4093f4305b93 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -699,7 +699,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @return a clone of this vector */ @SideEffectFree - public synchronized Object clone(@GuardSatisfied Vector this) { + public synchronized @Modifiable Object clone(@GuardSatisfied Vector this) { try { @SuppressWarnings("unchecked") Vector v = (Vector) super.clone(); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 2e86d17af041..8397bc488ab4 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -1144,7 +1144,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * * @return a shallow copy of this map */ - public ConcurrentSkipListMap clone() { + public @Modifiable ConcurrentSkipListMap clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListMap clone = diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index fd182a645a80..6c7b5d3eb1f5 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -189,7 +189,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public ConcurrentSkipListSet clone() { + public @Modifiable ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = 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 137c3083f196..0ea4fa62040d 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -328,7 +328,7 @@ public int lastIndexOf(E e, int index) { * * @return a clone of this list */ - public Object clone() { + public @Modifiable Object clone() { try { @SuppressWarnings("unchecked") CopyOnWriteArrayList clone = From 346776f7fc95fc7a764bbdce7a4266725f400129 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 8 Apr 2026 16:20:27 -0700 Subject: [PATCH 042/119] missed the import for polymod --- src/java.base/share/classes/java/util/ArrayList.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 14d142ece091..2a4e7ddbf905 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -34,6 +34,7 @@ import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; From 55bcb253e0ebd988057776531e8512bba87ed010 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Fri, 10 Apr 2026 20:29:05 -0700 Subject: [PATCH 043/119] Add `@DoesNotUnrefineReceiver` annotations (still need to add imports) --- .../classes/java/io/ObjectInputStream.java | 2 + .../classes/java/io/ObjectOutputStream.java | 2 + .../classes/java/lang/LiveStackFrame.java | 1 + .../classes/java/lang/LiveStackFrameInfo.java | 2 + .../share/classes/java/lang/String.java | 4 + .../share/classes/java/lang/StringLatin1.java | 16 +++ .../share/classes/java/lang/StringUTF16.java | 24 ++++ .../share/classes/java/lang/ThreadLocal.java | 1 + .../lang/invoke/AbstractConstantGroup.java | 4 +- .../classes/java/util/AbstractCollection.java | 17 ++- .../share/classes/java/util/AbstractList.java | 25 +++- .../share/classes/java/util/AbstractMap.java | 22 ++- .../classes/java/util/AbstractQueue.java | 6 + .../share/classes/java/util/AbstractSet.java | 2 + .../share/classes/java/util/ArrayDeque.java | 32 ++++- .../share/classes/java/util/ArrayList.java | 64 ++++++++- .../share/classes/java/util/Arrays.java | 4 +- .../share/classes/java/util/Collection.java | 18 ++- .../share/classes/java/util/Collections.java | 129 ++++++++++++++++-- .../share/classes/java/util/Deque.java | 29 +++- .../share/classes/java/util/EnumMap.java | 1 - .../share/classes/java/util/EnumSet.java | 5 + .../share/classes/java/util/HashMap.java | 39 +++++- .../share/classes/java/util/HashSet.java | 7 +- .../share/classes/java/util/Hashtable.java | 27 ++++ .../classes/java/util/IdentityHashMap.java | 25 +++- .../java/util/ImmutableCollections.java | 21 +++ .../share/classes/java/util/Iterator.java | 4 + .../share/classes/java/util/JumboEnumSet.java | 4 + .../classes/java/util/LinkedHashMap.java | 51 ++++++- .../classes/java/util/LinkedHashSet.java | 10 ++ .../share/classes/java/util/LinkedList.java | 84 +++++++++++- .../share/classes/java/util/List.java | 22 +-- .../share/classes/java/util/ListIterator.java | 6 + .../share/classes/java/util/Map.java | 32 ++++- .../share/classes/java/util/NavigableMap.java | 17 ++- .../share/classes/java/util/NavigableSet.java | 16 ++- .../classes/java/util/PrimitiveIterator.java | 14 ++ .../classes/java/util/PriorityQueue.java | 3 +- .../share/classes/java/util/Properties.java | 22 +++ .../share/classes/java/util/Queue.java | 9 +- .../classes/java/util/RegularEnumSet.java | 12 ++ .../java/util/ReverseOrderDequeView.java | 5 + .../java/util/ReverseOrderListView.java | 8 ++ .../java/util/ReverseOrderSortedMapView.java | 2 + .../java/util/ReverseOrderSortedSetView.java | 6 + .../java/util/SequencedCollection.java | 8 ++ .../share/classes/java/util/SequencedMap.java | 15 +- .../share/classes/java/util/SequencedSet.java | 3 + .../share/classes/java/util/Set.java | 13 +- .../share/classes/java/util/SortedMap.java | 4 + .../share/classes/java/util/SortedSet.java | 13 +- .../share/classes/java/util/Stack.java | 4 + .../share/classes/java/util/TreeMap.java | 43 +++++- .../share/classes/java/util/TreeSet.java | 38 ++++-- .../share/classes/java/util/Vector.java | 42 +++++- .../share/classes/java/util/WeakHashMap.java | 21 ++- .../util/concurrent/ArrayBlockingQueue.java | 18 ++- .../util/concurrent/ConcurrentHashMap.java | 44 +++++- .../concurrent/ConcurrentLinkedDeque.java | 32 ++++- .../concurrent/ConcurrentLinkedQueue.java | 14 +- .../concurrent/ConcurrentSkipListMap.java | 79 ++++++++++- .../concurrent/ConcurrentSkipListSet.java | 31 +++-- .../util/concurrent/CopyOnWriteArrayList.java | 103 +++++++++++++- .../util/concurrent/CopyOnWriteArraySet.java | 9 ++ .../java/util/concurrent/DelayQueue.java | 17 ++- .../util/concurrent/LinkedBlockingDeque.java | 45 +++++- .../util/concurrent/LinkedBlockingQueue.java | 19 ++- .../util/concurrent/LinkedTransferQueue.java | 25 +++- .../concurrent/PriorityBlockingQueue.java | 21 ++- .../util/concurrent/SynchronousQueue.java | 16 ++- .../java/util/stream/DoublePipeline.java | 1 + .../classes/java/util/stream/IntPipeline.java | 1 + .../java/util/stream/LongPipeline.java | 1 + .../classes/java/util/stream/Stream.java | 1 - .../internal/jimage/ImageStringsReader.java | 4 + .../jdk/internal/util/ArraysSupport.java | 4 + .../classes/javax/swing/DefaultListModel.java | 1 + .../util/SequencedCollection/SimpleDeque.java | 1 + 79 files changed, 1399 insertions(+), 148 deletions(-) diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index f8343235e34b..377d7b30e1f0 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -4099,6 +4099,7 @@ void clear() { /** * Returns number of handles registered in table. */ + @Pure int size() { return size; } @@ -4148,6 +4149,7 @@ public int get(int index) { return list[index]; } + @Pure public int size() { return size; } diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java index 1361cdc2c34e..7c25218bea74 100644 --- a/src/java.base/share/classes/java/io/ObjectOutputStream.java +++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java @@ -2344,6 +2344,7 @@ void clear() { /** * Returns the number of mappings currently in table. */ + @Pure int size() { return size; } @@ -2444,6 +2445,7 @@ void clear() { /** * Returns the number of mappings currently in table. */ + @Pure int size() { return htab.size(); } diff --git a/src/java.base/share/classes/java/lang/LiveStackFrame.java b/src/java.base/share/classes/java/lang/LiveStackFrame.java index 77a02d083c80..556ec2eb3e6c 100644 --- a/src/java.base/share/classes/java/lang/LiveStackFrame.java +++ b/src/java.base/share/classes/java/lang/LiveStackFrame.java @@ -125,6 +125,7 @@ public abstract class PrimitiveSlot { /** * Returns the size, in bytes, of the slot. */ + @Pure public abstract int size(); /** diff --git a/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java b/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java index b6583adf559f..335980a6e4cd 100644 --- a/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java +++ b/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java @@ -92,6 +92,7 @@ private static class PrimitiveSlot32 extends PrimitiveSlot { } @Override + @Pure public int size() { return 4; } @@ -114,6 +115,7 @@ private static class PrimitiveSlot64 extends PrimitiveSlot { } @Override + @Pure public int size() { return 8; } diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index b35e6124e152..8d67ce57c73e 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -2617,6 +2617,8 @@ public int hashCode() { * {@code endIndex}. * @since 21 */ + @Pure + @StaticallyExecutable public int indexOf(int ch, int beginIndex, int endIndex) { checkBoundsBeginEnd(beginIndex, endIndex, length()); return isLatin1() ? StringLatin1.indexOf(value, ch, beginIndex, endIndex) @@ -2781,6 +2783,8 @@ public int indexOf(int ch, int beginIndex, int endIndex) { * {@code endIndex}. * @since 21 */ + @Pure + @StaticallyExecutable public int indexOf(String str, int beginIndex, int endIndex) { if (str.length() == 1) { /* Simple optimization, can be omitted without behavioral impact */ diff --git a/src/java.base/share/classes/java/lang/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index 7c12e5711b39..f9586f8aaf29 100644 --- a/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/src/java.base/share/classes/java/lang/StringLatin1.java @@ -184,6 +184,8 @@ public static int compareToCI_UTF16(byte[] value, byte[] other) { return len1 - len2; } + @Pure + @StaticallyExecutable public static int hashCode(byte[] value) { return switch (value.length) { case 0 -> 0; @@ -192,6 +194,8 @@ public static int hashCode(byte[] value) { }; } + @Pure + @StaticallyExecutable public static int indexOf(byte[] value, int ch, int fromIndex, int toIndex) { if (!canEncode(ch)) { return -1; @@ -215,6 +219,8 @@ private static int indexOfChar(byte[] value, int ch, int fromIndex, int max) { return -1; } + @Pure + @StaticallyExecutable @IntrinsicCandidate public static int indexOf(byte[] value, byte[] str) { if (str.length == 0) { @@ -226,6 +232,8 @@ public static int indexOf(byte[] value, byte[] str) { return indexOf(value, value.length, str, str.length, 0); } + @Pure + @StaticallyExecutable @IntrinsicCandidate public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) { byte first = str[0]; @@ -249,6 +257,8 @@ public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount return -1; } + @Pure + @StaticallyExecutable public static int lastIndexOf(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) { int min = tgtCount - 1; @@ -277,6 +287,8 @@ public static int lastIndexOf(byte[] src, int srcCount, } } + @Pure + @StaticallyExecutable public static int lastIndexOf(final byte[] value, int ch, int fromIndex) { if (!canEncode(ch)) { return -1; @@ -580,6 +592,8 @@ public static String trim(byte[] value) { newString(value, st, len - st) : null; } + @Pure + @StaticallyExecutable public static int indexOfNonWhitespace(byte[] value) { int length = value.length; int left = 0; @@ -593,6 +607,8 @@ public static int indexOfNonWhitespace(byte[] value) { return left; } + @Pure + @StaticallyExecutable public static int lastIndexOfNonWhitespace(byte[] value) { int length = value.length; int right = length; diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index 73d858639909..9739aa9de5a9 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -411,6 +411,8 @@ public static int compareToCI_Latin1(byte[] value, byte[] other) { return -StringLatin1.compareToCI_UTF16(other, value); } + @Pure + @StaticallyExecutable public static int hashCode(byte[] value) { return switch (value.length) { case 0 -> 0; @@ -419,6 +421,8 @@ public static int hashCode(byte[] value) { }; } + @Pure + @StaticallyExecutable public static int indexOf(byte[] value, int ch, int fromIndex, int toIndex) { fromIndex = Math.max(fromIndex, 0); toIndex = Math.min(toIndex, value.length >> 1); @@ -434,6 +438,8 @@ public static int indexOf(byte[] value, int ch, int fromIndex, int toIndex) { } } + @Pure + @StaticallyExecutable @IntrinsicCandidate public static int indexOf(byte[] value, byte[] str) { if (str.length == 0) { @@ -445,6 +451,8 @@ public static int indexOf(byte[] value, byte[] str) { return indexOfUnsafe(value, length(value), str, length(str), 0); } + @Pure + @StaticallyExecutable @IntrinsicCandidate public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) { checkBoundsBeginEnd(fromIndex, valueCount, value); @@ -483,6 +491,8 @@ private static int indexOfUnsafe(byte[] value, int valueCount, byte[] str, int s /** * Handles indexOf Latin1 substring in UTF16 string. */ + @Pure + @StaticallyExecutable @IntrinsicCandidate public static int indexOfLatin1(byte[] value, byte[] str) { if (str.length == 0) { @@ -494,6 +504,8 @@ public static int indexOfLatin1(byte[] value, byte[] str) { return indexOfLatin1Unsafe(value, length(value), str, str.length, 0); } + @Pure + @StaticallyExecutable @IntrinsicCandidate public static int indexOfLatin1(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) { checkBoundsBeginEnd(fromIndex, srcCount, src); @@ -501,6 +513,8 @@ public static int indexOfLatin1(byte[] src, int srcCount, byte[] tgt, int tgtCou return indexOfLatin1Unsafe(src, srcCount, tgt, tgtCount, fromIndex); } + @Pure + @StaticallyExecutable public static int indexOfLatin1Unsafe(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) { assert fromIndex >= 0; assert tgtCount > 0; @@ -562,6 +576,8 @@ private static int indexOfSupplementary(byte[] value, int ch, int fromIndex, int } // srcCoder == UTF16 && tgtCoder == UTF16 + @Pure + @StaticallyExecutable public static int lastIndexOf(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) { assert fromIndex >= 0; @@ -597,6 +613,8 @@ public static int lastIndexOf(byte[] src, int srcCount, } } + @Pure + @StaticallyExecutable public static int lastIndexOf(byte[] value, int ch, int fromIndex) { if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { // handle most cases here (ch is a BMP code point or a @@ -1013,6 +1031,8 @@ public static String trim(byte[] value) { null; } + @Pure + @StaticallyExecutable public static int indexOfNonWhitespace(byte[] value) { int length = value.length >> 1; int left = 0; @@ -1026,6 +1046,8 @@ public static int indexOfNonWhitespace(byte[] value) { return left; } + @Pure + @StaticallyExecutable public static int lastIndexOfNonWhitespace(byte[] value) { int length = value.length >>> 1; int right = length; @@ -1463,6 +1485,8 @@ public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int l } // srcCoder == UTF16 && tgtCoder == LATIN1 + @Pure + @StaticallyExecutable public static int lastIndexOfLatin1(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) { assert fromIndex >= 0; diff --git a/src/java.base/share/classes/java/lang/ThreadLocal.java b/src/java.base/share/classes/java/lang/ThreadLocal.java index 01aad2fd7e44..c5cdf0e453e4 100644 --- a/src/java.base/share/classes/java/lang/ThreadLocal.java +++ b/src/java.base/share/classes/java/lang/ThreadLocal.java @@ -495,6 +495,7 @@ private ThreadLocalMap(ThreadLocalMap parentMap) { /** * Returns the number of elements in the map. */ + @Pure int size() { return size; } diff --git a/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java b/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java index 1863d17c0821..5cfceb9593d4 100644 --- a/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java +++ b/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java @@ -46,7 +46,9 @@ abstract class AbstractConstantGroup implements ConstantGroup { this.size = size; } - @Override public final int size() { + @Override + @Pure + public final int size() { return size; } diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index e95aa874bd39..f68628dc305e 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -29,20 +29,20 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; -import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -210,7 +210,6 @@ public boolean contains(@UnknownModifiability @GuardSatisfied AbstractCollection * @throws ArrayStoreException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T [] toArray(@UnknownModifiability @PolyNull T [] a) { // Estimate size of array; be prepared to see more or fewer elements @@ -282,6 +281,7 @@ private static T[] finishToArray(T[] r, Iterator it) { * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); } @@ -303,6 +303,7 @@ public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { @@ -366,6 +367,7 @@ public boolean containsAll(@UnknownModifiability @GuardSatisfied AbstractCollect * * @see #add(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Collection c) { boolean modified = false; for (E e : c) @@ -396,6 +398,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Coll * @see #remove(Object) * @see #contains(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -431,6 +434,7 @@ public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollecti * @see #remove(Object) * @see #contains(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -460,6 +464,7 @@ public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollecti * * @throws UnsupportedOperationException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index 2dea3eee4646..10a0755237b7 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -32,17 +32,18 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -137,6 +138,7 @@ protected AbstractList() { * prevents it from being added to this list */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { add(size(), e); return true; @@ -163,6 +165,7 @@ public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -180,6 +183,7 @@ public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -194,6 +198,7 @@ public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"t * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); } @@ -213,6 +218,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In * @throws NullPointerException {@inheritDoc} */ @Pure + @StaticallyExecutable public @GTENegativeOne int indexOf(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(); if (o==null) { @@ -240,6 +246,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In * @throws NullPointerException {@inheritDoc} */ @Pure + @StaticallyExecutable public @GTENegativeOne int lastIndexOf(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(size()); if (o==null) { @@ -272,6 +279,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { removeRange(0, size()); } @@ -296,6 +304,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); boolean modified = false; @@ -329,7 +338,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) { return new Itr(); } @@ -341,7 +350,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * * @see #listIterator(int) */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) { return listIterator(0); } @@ -368,7 +377,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink AbstractList this, final @IndexOrHigh({"this"}) int index) { + public @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable AbstractList this, final @IndexOrHigh({"this"}) int index) { rangeCheckForAdd(index); return new ListItr(index); @@ -442,6 +451,7 @@ private class ListItr extends Itr implements ListIterator { cursor = index; } + @Pure public boolean hasPrevious() { return cursor != 0; } @@ -531,7 +541,7 @@ public void add(E e) { * {@code (fromIndex > toIndex)} */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + public @PolyGrowShrink @PolyModifiable List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { subListRangeCheck(fromIndex, toIndex, size()); return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : @@ -631,6 +641,7 @@ public int hashCode(@UnknownModifiability @GuardSatisfied AbstractList this) * @param fromIndex index of first element to be removed * @param toIndex index after last element to be removed */ + @DoesNotUnrefineReceiver("modifiability") protected void removeRange(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i this, K key, V value) { throw new UnsupportedOperationException(); } @@ -271,6 +273,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); Entry correctEntry = null; @@ -316,6 +319,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); @@ -333,6 +337,7 @@ public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this * * @throws UnsupportedOperationException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { entrySet().clear(); } @@ -403,6 +408,7 @@ public K next(/*@NonEmpty Iterator this*/) { return i.next().getKey(); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); } @@ -420,11 +426,13 @@ public boolean isEmpty() { return AbstractMap.this.isEmpty(); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { AbstractMap.this.clear(); } @EnsuresNonEmptyIf(result = true, expression = "this") + @Pure public boolean contains(@UnknownSignedness Object k) { return AbstractMap.this.containsKey(k); } @@ -470,6 +478,7 @@ public V next(/*@NonEmpty Iterator this*/) { return i.next().getValue(); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); } @@ -487,6 +496,7 @@ public boolean isEmpty() { return AbstractMap.this.isEmpty(); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { AbstractMap.this.clear(); } @@ -726,6 +736,7 @@ public V getValue(AbstractMap.@GuardSatisfied SimpleEntry this) { * @param value new value to be stored in this entry * @return the old value corresponding to the entry */ + @DoesNotUnrefineReceiver("modifiability") public V setValue(AbstractMap.@GuardSatisfied SimpleEntry this, V value) { V oldValue = this.value; this.value = value; @@ -971,17 +982,26 @@ public String toString(AbstractMap.@GuardSatisfied SimpleImmutableEntry th public boolean add(E t) { throw uoe(); } public boolean addAll(Collection c) { throw uoe(); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { view().clear(); } + @Pure public boolean contains(Object o) { return view().contains(o); } + @Pure public boolean containsAll(Collection c) { return view().containsAll(c); } public void forEach(Consumer c) { view().forEach(c); } + @Pure public boolean isEmpty() { return view().isEmpty(); } public Iterator iterator() { return view().iterator(); } public Stream parallelStream() { return view().parallelStream(); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object o) { return view().remove(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return view().removeAll(c); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return view().removeIf(filter); } + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return view().retainAll(c); } + @Pure public int size() { return view().size(); } public Spliterator spliterator() { return view().spliterator(); } public Stream stream() { return view().stream(); } diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index b1272f0d6f5a..f76dc1db8253 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -42,6 +42,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.framework.qual.AnnotatedFor; /** @@ -102,6 +103,7 @@ public abstract class AbstractQueue * prevents it from being added to this queue */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { if (offer(e)) return true; @@ -120,6 +122,7 @@ public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { E x = poll(); if (x != null) @@ -139,6 +142,7 @@ public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { E x = peek(); if (x != null) @@ -154,6 +158,7 @@ public E element(@GuardSatisfied @NonEmpty AbstractQueue this) { *

This implementation repeatedly invokes {@link #poll poll} until it * returns {@code null}. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) { while (poll() != null) ; @@ -188,6 +193,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) * this time due to insertion restrictions * @see #add(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable @GuardSatisfied AbstractQueue this, Collection c) { if (c == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index 777d0f98684e..b78c499ed229 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -176,6 +177,7 @@ public int hashCode(@UnknownModifiability @GuardSatisfied AbstractSet this) { * @see #remove(Object) * @see #contains(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 6e449bd96484..2974f1335515 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -52,6 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -305,6 +306,7 @@ static final E nonNullElementAt(@PolyNull @PolySigned Object[] es, int i) { * @param e the element to add * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); @@ -322,6 +324,7 @@ public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { * @param e the element to add * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); @@ -341,6 +344,7 @@ public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { * @throws NullPointerException if the specified collection or any * of its elements are null */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable ArrayDeque this, Collection c) { final int s, needed; if ((needed = (s = size()) + c.size() + 1 - elements.length) > 0) @@ -360,6 +364,7 @@ private void copyElements(Collection c) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(@Growable ArrayDeque this, E e) { addFirst(e); return true; @@ -372,6 +377,7 @@ public boolean offerFirst(@Growable ArrayDeque this, E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(@Growable ArrayDeque this, E e) { addLast(e); return true; @@ -380,6 +386,7 @@ public boolean offerLast(@Growable ArrayDeque this, E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollFirst(); if (e == null) @@ -390,6 +397,7 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollLast(); if (e == null) @@ -397,6 +405,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque< return e; } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; final int h; @@ -408,6 +417,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque< return e; } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; final int t; @@ -420,6 +430,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque< /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getFirst(@GuardSatisfied @NonEmpty ArrayDeque this) { E e = elementAt(elements, head); if (e == null) @@ -430,6 +441,7 @@ public E getFirst(@GuardSatisfied @NonEmpty ArrayDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getLast(@GuardSatisfied @NonEmpty ArrayDeque this) { final Object[] es = elements; E e = elementAt(es, dec(tail, es.length)); @@ -461,6 +473,7 @@ public E getLast(@GuardSatisfied @NonEmpty ArrayDeque this) { * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = elements; @@ -489,6 +502,7 @@ public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink Arra * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = elements; @@ -517,6 +531,7 @@ public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Array * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable @GuardSatisfied ArrayDeque this, E e) { addLast(e); return true; @@ -531,6 +546,7 @@ public boolean add(@Growable @GuardSatisfied ArrayDeque this, E e) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable @GuardSatisfied ArrayDeque this, E e) { return offerLast(e); } @@ -546,6 +562,7 @@ public boolean offer(@Growable @GuardSatisfied ArrayDeque this, E e) { * @return the head of the queue represented by this deque * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); } @@ -560,6 +577,7 @@ public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque t * @return the head of the queue represented by this deque, or * {@code null} if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { return pollFirst(); } @@ -574,6 +592,7 @@ public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque t * @return the head of the queue represented by this deque * @throws NoSuchElementException {@inheritDoc} */ + @SideEffectFree public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { return getFirst(); } @@ -603,6 +622,7 @@ public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { * @param e the element to push * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void push(@Growable @GuardSatisfied ArrayDeque this, E e) { addFirst(e); } @@ -617,6 +637,7 @@ public void push(@Growable @GuardSatisfied ArrayDeque this, E e) { * of the stack represented by this deque) * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); } @@ -699,11 +720,11 @@ public boolean isEmpty(@GuardSatisfied ArrayDeque this) { * @return an iterator over the elements in this deque */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ArrayDeque this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ArrayDeque this) { return new DeqIterator(); } - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ArrayDeque this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ArrayDeque this) { return new DescendingIterator(); } @@ -744,6 +765,7 @@ void postDelete(boolean leftShifted) { cursor = dec(cursor, elements.length); } + @DoesNotUnrefineReceiver("modifiability") public final void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -932,6 +954,7 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink ArrayDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -940,6 +963,7 @@ public boolean removeIf(@Shrinkable @CanShrink ArrayDeque this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -948,6 +972,7 @@ public boolean removeAll(@CanShrink ArrayDeque this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -1064,6 +1089,7 @@ public boolean contains(@GuardSatisfied ArrayDeque this, @GuardSatisfied @Nul * @param o element to be removed from this deque, if present * @return {@code true} if this deque contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -1072,6 +1098,7 @@ public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, * Removes all of the elements from this deque. * The deque will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { circularClear(elements, head, tail); head = tail = 0; @@ -1162,7 +1189,6 @@ private T[] toArray(Class klazz) { * this deque * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { final int size; diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 2a4e7ddbf905..17267e39925f 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -30,11 +30,11 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -45,6 +45,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -227,6 +228,7 @@ public class ArrayList extends AbstractList * list's current size. An application can use this operation to minimize * the storage of an {@code ArrayList} instance. */ + @SideEffectFree public void trimToSize(@GuardSatisfied ArrayList this) { modCount++; if (size < elementData.length) { @@ -243,6 +245,7 @@ public void trimToSize(@GuardSatisfied ArrayList this) { * * @param minCapacity the desired minimum capacity */ + @SideEffectFree public void ensureCapacity(@GuardSatisfied ArrayList this, int minCapacity) { if (minCapacity > elementData.length && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA @@ -319,6 +322,7 @@ public boolean contains(@GuardSatisfied ArrayList this, @GuardSatisfied @Null * or -1 if there is no such index. */ @Pure + @StaticallyExecutable public @GTENegativeOne int indexOf(@GuardSatisfied ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return indexOfRange(o, 0, size); } @@ -349,6 +353,7 @@ int indexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int star * or -1 if there is no such index. */ @Pure + @StaticallyExecutable public @GTENegativeOne int lastIndexOf(@GuardSatisfied ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return lastIndexOfRange(o, 0, size); } @@ -433,7 +438,6 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * this list * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length < size) @@ -476,6 +480,7 @@ public E get(@GuardSatisfied ArrayList this, @NonNegative int index) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getFirst() { if (size == 0) { throw new NoSuchElementException(); @@ -490,6 +495,7 @@ public E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getLast() { int last = size - 1; if (last < 0) { @@ -509,6 +515,7 @@ public E getLast() { * @throws IndexOutOfBoundsException {@inheritDoc} */ @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(@Replaceable @GuardSatisfied ArrayList this, @NonNegative int index, E element) { Objects.checkIndex(index, size); E oldValue = elementData(index); @@ -572,6 +579,7 @@ public void add(@Growable @GuardSatisfied ArrayList this, @NonNegative int in * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable ArrayList this, E element) { add(0, element); } @@ -581,6 +589,7 @@ public void addFirst(@Growable ArrayList this, E element) { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable ArrayList this, E element) { add(element); } @@ -594,6 +603,7 @@ public void addLast(@Growable ArrayList this, E element) { * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @NonNegative int index) { Objects.checkIndex(index, size); final Object[] es = elementData; @@ -610,6 +620,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @NonNe * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable ArrayList this) { if (size == 0) { throw new NoSuchElementException(); @@ -627,6 +638,7 @@ public E removeFirst(@Shrinkable ArrayList this) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable ArrayList this) { int last = size - 1; if (last < 0) { @@ -708,6 +720,7 @@ private void checkForComodification(final int expectedModCount) { /** * {@inheritDoc} */ + @Pure public int hashCode() { int expectedModCount = modCount; int hash = hashCodeRange(0, size); @@ -715,6 +728,7 @@ public int hashCode() { return hash; } + @Pure int hashCodeRange(int from, int to) { final Object[] es = elementData; if (to > es.length) { @@ -741,6 +755,7 @@ int hashCodeRange(int from, int to) { * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { final Object[] es = elementData; final int size = this.size; @@ -777,6 +792,7 @@ private void fastRemove(Object[] es, int i) { * Removes all of the elements from this list. The list will * be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayList this) { modCount++; final Object[] es = elementData; @@ -920,6 +936,7 @@ private static String outOfBoundsMsg(int fromIndex, int toIndex) { * or if the specified collection is null * @see Collection#contains(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink ArrayList this, Collection c) { return batchRemove(c, false, 0, size); } @@ -940,6 +957,7 @@ public boolean removeAll(@Shrinkable @CanShrink ArrayList this, Collection this, Collection c) { return batchRemove(c, true, 0, size); } @@ -1052,7 +1070,7 @@ private void readObject(java.io.ObjectInputStream s) * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink ArrayList this, @NonNegative int index) { + public @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable ArrayList this, @NonNegative int index) { rangeCheckForAdd(index); return new ListItr(index); } @@ -1065,7 +1083,7 @@ private void readObject(java.io.ObjectInputStream s) * * @see #listIterator(int) */ - public @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink ArrayList this) { + public @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable ArrayList this) { return new ListItr(0); } @@ -1077,7 +1095,7 @@ private void readObject(java.io.ObjectInputStream s) * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink Iterator iterator(@PolyModifiable @PolyGrowShrink ArrayList this) { + public @PolyGrowShrink @PolyModifiable Iterator iterator(@PolyGrowShrink @PolyModifiable ArrayList this) { return new Itr(); } @@ -1100,6 +1118,7 @@ public boolean hasNext() { @SuppressWarnings("unchecked") @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { checkForComodification(); int i = cursor; @@ -1112,6 +1131,7 @@ public E next(@NonEmpty Itr this) { return (E) elementData[lastRet = i]; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -1161,19 +1181,23 @@ private class ListItr extends Itr implements ListIterator { cursor = index; } + @Pure public boolean hasPrevious() { return cursor != 0; } + @DoesNotUnrefineReceiver("modifiability") public int nextIndex() { return cursor; } + @DoesNotUnrefineReceiver("modifiability") public int previousIndex() { return cursor - 1; } @SuppressWarnings("unchecked") + @DoesNotUnrefineReceiver("modifiability") public E previous() { checkForComodification(); int i = cursor - 1; @@ -1186,6 +1210,7 @@ public E previous() { return (E) elementData[lastRet = i]; } + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); @@ -1198,6 +1223,7 @@ public void set(E e) { } } + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { checkForComodification(); @@ -1242,7 +1268,8 @@ public void add(E e) { * @throws IndexOutOfBoundsException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink ArrayList this, @NonNegative int fromIndex, @NonNegative int toIndex) { + @DoesNotUnrefineReceiver("modifiability") + public @PolyGrowShrink @PolyModifiable List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink ArrayList this, @NonNegative int fromIndex, @NonNegative int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList<>(this, fromIndex, toIndex); } @@ -1275,6 +1302,7 @@ private SubList(SubList parent, int fromIndex, int toIndex) { this.modCount = parent.modCount; } + @DoesNotUnrefineReceiver("modifiability") public E set(@NonNegative int index, E element) { Objects.checkIndex(index, size); checkForComodification(); @@ -1283,6 +1311,7 @@ public E set(@NonNegative int index, E element) { return oldValue; } + @Pure public E get(@NonNegative int index) { Objects.checkIndex(index, size); checkForComodification(); @@ -1295,6 +1324,7 @@ public E get(@NonNegative int index) { return size; } + @DoesNotUnrefineReceiver("modifiability") public void add(@NonNegative int index, E element) { rangeCheckForAdd(index); checkForComodification(); @@ -1302,6 +1332,7 @@ public void add(@NonNegative int index, E element) { updateSizeAndModCount(1); } + @DoesNotUnrefineReceiver("modifiability") public E remove(@NonNegative int index) { Objects.checkIndex(index, size); checkForComodification(); @@ -1310,16 +1341,19 @@ public E remove(@NonNegative int index) { return result; } + @DoesNotUnrefineReceiver("modifiability") protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); root.removeRange(offset + fromIndex, offset + toIndex); updateSizeAndModCount(fromIndex - toIndex); } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { return addAll(this.size, c); } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@NonNegative int index, Collection c) { rangeCheckForAdd(index); int cSize = c.size(); @@ -1331,14 +1365,17 @@ public boolean addAll(@NonNegative int index, Collection c) { return true; } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { root.replaceAllRange(operator, offset, offset + size); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return batchRemove(c, false); } + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return batchRemove(c, true); } @@ -1353,6 +1390,7 @@ private boolean batchRemove(Collection c, boolean complement) { return modified; } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { checkForComodification(); int oldSize = root.size; @@ -1362,6 +1400,7 @@ public boolean removeIf(Predicate filter) { return modified; } + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(SubList<@PolyNull @PolySigned E> this) { checkForComodification(); return Arrays.copyOfRange(root.elementData, offset, offset + size); @@ -1379,6 +1418,7 @@ public boolean removeIf(Predicate filter) { return a; } + @Pure public boolean equals(@Nullable Object o) { if (o == this) { return true; @@ -1393,18 +1433,23 @@ public boolean equals(@Nullable Object o) { return equal; } + @Pure public int hashCode() { int hash = root.hashCodeRange(offset, offset + size); checkForComodification(); return hash; } + @Pure + @StaticallyExecutable public int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { int index = root.indexOfRange(o, offset, offset + size); checkForComodification(); return index >= 0 ? index - offset : -1; } + @Pure + @StaticallyExecutable public int lastIndexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { int index = root.lastIndexOfRange(o, offset, offset + size); checkForComodification(); @@ -1450,6 +1495,7 @@ public E next(/*@NonEmpty ListIterator this*/) { return (E) elementData[offset + (lastRet = i)]; } + @Pure public boolean hasPrevious() { return cursor != 0; } @@ -1647,6 +1693,7 @@ public int characteristics() { * @throws NullPointerException {@inheritDoc} */ @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(Consumer action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @@ -1802,6 +1849,7 @@ private static boolean isClear(long[] bits, int i) { * @throws NullPointerException {@inheritDoc} */ @Override + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink ArrayList this, Predicate filter) { return removeIf(filter, 0, size); } @@ -1845,6 +1893,7 @@ boolean removeIf(@Shrinkable @CanShrink ArrayList this, Predicate @SuppressWarnings({"unchecked"}) @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable ArrayList this, UnaryOperator operator) { replaceAllRange(operator, 0, size); // TODO(8203662): remove increment of modCount from ... @@ -1863,6 +1912,7 @@ private void replaceAllRange(@Replaceable ArrayList this, UnaryOperator op @Override @SuppressWarnings("unchecked") + @DoesNotUnrefineReceiver("modifiability") public void sort(@Replaceable ArrayList this, Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index b293cc708df7..56e8ca0b6b7e 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -4305,7 +4305,6 @@ private static class ArrayList extends AbstractList return Arrays.copyOf(a, a.length, Object[].class); } - @SideEffectFree @Override @SuppressWarnings("unchecked") public T[] toArray(T[] a) { @@ -4320,6 +4319,7 @@ public T[] toArray(T[] a) { } @Override + @Pure public E get(int index) { return a[index]; } @@ -4332,6 +4332,8 @@ public E set(int index, E element) { } @Override + @Pure + @StaticallyExecutable public int indexOf(Object o) { E[] a = this.a; if (o == null) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index bbe27d23ad7d..d61920d8cf76 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -29,12 +29,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -43,6 +43,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -416,7 +417,6 @@ public interface Collection extends Iterable { * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T [] toArray(@UnknownModifiability Collection this, @PolyNull T[] a); /** @@ -454,6 +454,7 @@ public interface Collection extends Iterable { * @throws NullPointerException if the generator function is null * @since 11 */ + @SideEffectFree default T[] toArray(@UnknownModifiability Collection this, IntFunction generator) { return toArray(generator.apply(0)); } @@ -494,6 +495,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, E e); /** @@ -516,6 +518,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, @UnknownSignedness Object o); @@ -568,6 +571,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Collection c); /** @@ -593,6 +597,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Collection c); /** @@ -617,6 +622,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; @@ -652,6 +658,7 @@ default boolean removeIf(@Shrinkable @CanShrink Collection this, Predicate this, Collection c); /** @@ -661,6 +668,7 @@ default boolean removeIf(@Shrinkable @CanShrink Collection this, Predicate this); @@ -791,6 +799,7 @@ default Spliterator spliterator(@UnknownModifiability Collection this) { * @return a sequential {@code Stream} over the elements in this collection * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyNonEmpty Stream stream(@UnknownModifiability @PolyNonEmpty Collection this) { return StreamSupport.stream(spliterator(), false); } @@ -812,6 +821,7 @@ default Spliterator spliterator(@UnknownModifiability Collection this) { * collection * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default Stream parallelStream(@UnknownModifiability Collection this) { return StreamSupport.stream(spliterator(), true); } diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 51de9366a528..59a382201b91 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -29,12 +29,12 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; -import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -49,6 +49,7 @@ import org.checkerframework.common.value.qual.ArrayLen; import org.checkerframework.common.value.qual.MinLen; import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -965,6 +966,7 @@ public static boolean replaceAll(@Replaceable List list, @Nullable T oldV * @since 1.4 */ @Pure + @StaticallyExecutable public static @GTENegativeOne int indexOfSubList(@UnknownModifiability @GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); @@ -1019,6 +1021,7 @@ public static boolean replaceAll(@Replaceable List list, @Nullable T oldV * @since 1.4 */ @Pure + @StaticallyExecutable public static @GTENegativeOne int lastIndexOfSubList(@UnknownModifiability @GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); @@ -1118,7 +1121,9 @@ static class UnmodifiableCollection implements Collection, Serializable { public @PolyNull @PolySigned Object[] toArray(Collections.UnmodifiableCollection<@PolyNull @PolySigned E> this) {return c.toArray();} @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) {return c.toArray(a);} + @SideEffectFree public T[] toArray(IntFunction f) {return c.toArray(f);} + @SideEffectFree public String toString() {return c.toString();} @SideEffectFree @@ -1131,10 +1136,12 @@ static class UnmodifiableCollection implements Collection, Serializable { public boolean hasNext() {return i.hasNext();} @SideEffectsOnly("this") public E next(/*@NonEmpty Iterator this*/) {return i.next();} + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public void forEachRemaining(Consumer action) { // Use backing collection version i.forEachRemaining(action); @@ -1142,10 +1149,12 @@ public void forEachRemaining(Consumer action) { }; } + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") public boolean add(E e) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { throw new UnsupportedOperationException(); } @@ -1154,25 +1163,31 @@ public boolean remove(@UnknownSignedness Object o) { public boolean containsAll(Collection coll) { return c.containsAll(coll); } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection coll) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection coll) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection coll) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { throw new UnsupportedOperationException(); } // Override default methods in Collection @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(Consumer action) { c.forEach(action); } @Override + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { throw new UnsupportedOperationException(); } @@ -1184,11 +1199,13 @@ public Spliterator spliterator() { } @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public Stream stream() { return (Stream)c.stream(); } @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public Stream parallelStream() { return (Stream)c.parallelStream(); } @@ -1246,30 +1263,37 @@ private SequencedCollection sc() { // Even though this wrapper class is serializable, the reversed view is effectively // not serializable because it points to the reversed collection view, which usually isn't // serializable. + @DoesNotUnrefineReceiver("modifiability") public SequencedCollection reversed() { return new UnmodifiableSequencedCollection<>(sc().reversed()); } + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { throw new UnsupportedOperationException(); } + @Pure public E getFirst() { return sc().getFirst(); } + @Pure public E getLast() { return sc().getLast(); } + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { throw new UnsupportedOperationException(); } @@ -1308,7 +1332,9 @@ static class UnmodifiableSet extends UnmodifiableCollection private static final long serialVersionUID = -9215047833775013803L; UnmodifiableSet(Set s) {super(s);} + @Pure public boolean equals(Object o) {return o == this || c.equals(o);} + @Pure public int hashCode() {return c.hashCode();} } @@ -1346,7 +1372,9 @@ static class UnmodifiableSequencedSet extends UnmodifiableSequencedCollection private static final long serialVersionUID = -2153469532349793522L; UnmodifiableSequencedSet(SequencedSet s) {super(s);} + @Pure public boolean equals(Object o) {return o == this || c.equals(o);} + @Pure public int hashCode() {return c.hashCode();} @SuppressWarnings("unchecked") @@ -1357,6 +1385,7 @@ private SequencedSet ss() { // Even though this wrapper class is serializable, the reversed view is effectively // not serializable because it points to the reversed set view, which usually isn't // serializable. + @DoesNotUnrefineReceiver("modifiability") public SequencedSet reversed() { return new UnmodifiableSequencedSet<>(ss().reversed()); } @@ -1400,19 +1429,25 @@ static class UnmodifiableSortedSet UnmodifiableSortedSet(SortedSet s) {super(s); ss = s;} + @Pure public Comparator comparator() {return ss.comparator();} + @DoesNotUnrefineReceiver("modifiability") public SortedSet subSet(E fromElement, E toElement) { return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement)); } + @DoesNotUnrefineReceiver("modifiability") public SortedSet headSet(E toElement) { return new UnmodifiableSortedSet<>(ss.headSet(toElement)); } + @DoesNotUnrefineReceiver("modifiability") public SortedSet tailSet(E fromElement) { return new UnmodifiableSortedSet<>(ss.tailSet(fromElement)); } + @Pure public E first() {return ss.first();} + @Pure public E last() {return ss.last();} } @@ -1485,27 +1520,38 @@ public EmptyNavigableSet() { UnmodifiableNavigableSet(NavigableSet s) {super(s); ns = s;} + @Pure public E lower(E e) { return ns.lower(e); } + @Pure public E floor(E e) { return ns.floor(e); } + @Pure public E ceiling(E e) { return ns.ceiling(e); } + @Pure public E higher(E e) { return ns.higher(e); } + @DoesNotUnrefineReceiver("modifiability") public E pollFirst() { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public E pollLast() { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public NavigableSet descendingSet() { return new UnmodifiableNavigableSet<>(ns.descendingSet()); } + @DoesNotUnrefineReceiver("modifiability") public Iterator descendingIterator() { return descendingSet().iterator(); } + @DoesNotUnrefineReceiver("modifiability") public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { return new UnmodifiableNavigableSet<>( ns.subSet(fromElement, fromInclusive, toElement, toInclusive)); } + @DoesNotUnrefineReceiver("modifiability") public NavigableSet headSet(E toElement, boolean inclusive) { return new UnmodifiableNavigableSet<>( ns.headSet(toElement, inclusive)); } + @DoesNotUnrefineReceiver("modifiability") public NavigableSet tailSet(E fromElement, boolean inclusive) { return new UnmodifiableNavigableSet<>( ns.tailSet(fromElement, inclusive)); @@ -1555,36 +1601,50 @@ static class UnmodifiableList extends UnmodifiableCollection this.list = list; } + @Pure public boolean equals(Object o) {return o == this || list.equals(o);} + @Pure public int hashCode() {return list.hashCode();} + @Pure public E get(int index) {return list.get(index);} + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { throw new UnsupportedOperationException(); } + @Pure + @StaticallyExecutable public int indexOf(Object o) {return list.indexOf(o);} + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) {return list.lastIndexOf(o);} + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { throw new UnsupportedOperationException(); } public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty UnmodifiableList this) {return listIterator(0);} + @DoesNotUnrefineReceiver("modifiability") public ListIterator listIterator(final int index) { return new ListIterator<>() { private final ListIterator i @@ -1952,6 +2012,7 @@ public void forEachRemaining(Consumer> action) { } @SuppressWarnings("unchecked") + @SideEffectFree public Object[] toArray() { Object[] a = c.toArray(); for (int i=0; i @Nullable T[] toArray(@PolyNull T[] a) { // We don't pass a to c.toArray, to avoid window of // vulnerability wherein an unscrupulous multithreaded client @@ -2151,6 +2213,7 @@ static class UnmodifiableSortedMap private final SortedMap sm; UnmodifiableSortedMap(SortedMap m) {super(m); sm = m; } + @Pure public Comparator comparator() { return sm.comparator(); } @SideEffectFree public SortedMap subMap(K fromKey, K toKey) @@ -2357,11 +2420,11 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) * @param c the collection to be "wrapped" in a synchronized collection. * @return a synchronized view of the specified collection. */ - public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection synchronizedCollection(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { + public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection c) { return new SynchronizedCollection<>(c); } - static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection synchronizedCollection(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection c, Object mutex) { + static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection c, Object mutex) { return new SynchronizedCollection<>(c, mutex); } @@ -2405,10 +2468,10 @@ public boolean contains(@UnknownSignedness Object o) { public @PolyNull @PolySigned Object[] toArray(Collections.SynchronizedCollection<@PolyNull @PolySigned E> this) { synchronized (mutex) {return c.toArray();} } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { synchronized (mutex) {return c.toArray(a);} } + @SideEffectFree public T[] toArray(IntFunction f) { synchronized (mutex) {return c.toArray(f);} } @@ -2599,6 +2662,7 @@ static class SynchronizedSortedSet ss = s; } + @Pure public Comparator comparator() { synchronized (mutex) {return ss.comparator();} } @@ -2773,13 +2837,13 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @param list the list to be "wrapped" in a synchronized list. * @return a synchronized view of the specified list. */ - public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty List synchronizedList(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List list) { + public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list) : new SynchronizedList<>(list)); } - static @PolyModifiable @PolyGrowShrink @PolyNonEmpty List synchronizedList(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List list, Object mutex) { + static @PolyGrowShrink @PolyModifiable @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List list, Object mutex) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list, mutex) : new SynchronizedList<>(list, mutex)); @@ -2815,6 +2879,7 @@ public int hashCode() { synchronized (mutex) {return list.hashCode();} } + @Pure public E get(int index) { synchronized (mutex) {return list.get(index);} } @@ -2828,9 +2893,13 @@ public E remove(int index) { synchronized (mutex) {return list.remove(index);} } + @Pure + @StaticallyExecutable public int indexOf(Object o) { synchronized (mutex) {return list.indexOf(o);} } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { synchronized (mutex) {return list.lastIndexOf(o);} } @@ -3183,6 +3252,7 @@ static class SynchronizedSortedMap sm = m; } + @Pure public Comparator comparator() { synchronized (mutex) {return sm.comparator();} } @@ -3450,7 +3520,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { * @return a dynamically typesafe view of the specified collection * @since 1.5 */ - public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection checkedCollection(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Collection c, + public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection checkedCollection(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection c, Class type) { return new CheckedCollection<>(c, type); } @@ -3501,6 +3571,7 @@ private String badElementMsg(Object o) { public @PolyNull @PolySigned Object[] toArray(Collections.CheckedCollection<@PolyNull @PolySigned E> this) { return c.toArray(); } @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return c.toArray(a); } + @SideEffectFree public T[] toArray(IntFunction f) { return c.toArray(f); } public String toString() { return c.toString(); } public boolean remove(@UnknownSignedness Object o) { return c.remove(o); } @@ -3620,7 +3691,7 @@ public boolean removeIf(Predicate filter) { * @return a dynamically typesafe view of the specified queue * @since 1.8 */ - public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Queue checkedQueue(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Queue queue, Class type) { + public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Queue checkedQueue(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Queue queue, Class type) { return new CheckedQueue<>(queue, type); } @@ -3749,8 +3820,11 @@ static class CheckedSortedSet extends CheckedSet ss = s; } + @Pure public Comparator comparator() { return ss.comparator(); } + @Pure public E first() { return ss.first(); } + @Pure public E last() { return ss.last(); } public SortedSet subSet(E fromElement, E toElement) { @@ -3814,9 +3888,13 @@ static class CheckedNavigableSet extends CheckedSortedSet ns = s; } + @Pure public E lower(E e) { return ns.lower(e); } + @Pure public E floor(E e) { return ns.floor(e); } + @Pure public E ceiling(E e) { return ns.ceiling(e); } + @Pure public E higher(E e) { return ns.higher(e); } public E pollFirst() { return ns.pollFirst(); } public E pollLast() {return ns.pollLast(); } @@ -3875,7 +3953,7 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @return a dynamically typesafe view of the specified list * @since 1.5 */ - public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty List checkedList(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List list, Class type) { + public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty List checkedList(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List list, Class type) { return (list instanceof RandomAccess ? new CheckedRandomAccessList<>(list, type) : new CheckedList<>(list, type)); @@ -3898,11 +3976,19 @@ static class CheckedList this.list = list; } + @Pure public boolean equals(Object o) { return o == this || list.equals(o); } + @Pure public int hashCode() { return list.hashCode(); } + @Pure + @StaticallyExecutable public E get(int index) { return list.get(index); } public E remove(int index) { return list.remove(index); } + @Pure + @StaticallyExecutable public int indexOf(Object o) { return list.indexOf(o); } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public E set(int index, E element) { @@ -3927,6 +4013,7 @@ public ListIterator listIterator(final int index) { public boolean hasNext() { return i.hasNext(); } @SideEffectsOnly("this") public E next(/*@NonEmpty ListIterator this*/) { return i.next(); } + @Pure public boolean hasPrevious() { return i.hasPrevious(); } public E previous() { return i.previous(); } public int nextIndex() { return i.nextIndex(); } @@ -4265,6 +4352,7 @@ public void forEachRemaining(Consumer> action) { } @SuppressWarnings("unchecked") + @SideEffectFree public Object[] toArray() { Object[] source = s.toArray(); @@ -4470,6 +4558,7 @@ static class CheckedSortedMap extends CheckedMap sm = m; } + @Pure public Comparator comparator() { return sm.comparator(); } public K firstKey() { return sm.firstKey(); } public K lastKey() { return sm.lastKey(); } @@ -4549,6 +4638,7 @@ static class CheckedNavigableMap extends CheckedSortedMap nm = m; } + @Pure public Comparator comparator() { return nm.comparator(); } public K firstKey() { return nm.firstKey(); } public K lastKey() { return nm.lastKey(); } @@ -4753,6 +4843,7 @@ private static class EmptyListIterator static final EmptyListIterator EMPTY_ITERATOR = new EmptyListIterator<>(); + @Pure public boolean hasPrevious() { return false; } public E previous() { throw new NoSuchElementException(); } public int nextIndex() { return 0; } @@ -4856,7 +4947,6 @@ public void clear() {} @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.EmptySet<@PolyNull @PolySigned E> this) { return new Object[0]; } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length > 0) a[0] = null; @@ -5000,13 +5090,13 @@ public void clear() {} @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.EmptyList<@PolyNull @PolySigned E> this) { return new Object[0]; } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length > 0) a[0] = null; return a; } + @Pure public E get(int index) { throw new IndexOutOfBoundsException("Index: "+index); } @@ -5405,6 +5495,7 @@ public Iterator iterator() { @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object obj) {return eq(obj, element);} + @Pure public E get(int index) { if (index != 0) throw new IndexOutOfBoundsException("Index: "+index+", Size: 1"); @@ -5633,14 +5724,19 @@ public boolean contains(@UnknownSignedness Object obj) { return n != 0 && eq(obj, element); } + @Pure + @StaticallyExecutable public int indexOf(Object o) { return contains(o) ? 0 : -1; } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { return contains(o) ? n - 1 : -1; } + @Pure public E get(int index) { Objects.checkIndex(index, n); return element; @@ -5657,6 +5753,7 @@ public void forEach(Consumer action) { } } + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.CopiesList<@PolyNull @PolySigned E> this) { final Object[] a = new Object[n]; if (element != null) @@ -5664,7 +5761,6 @@ public void forEach(Consumer action) { return a; } - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { final int n = this.n; @@ -6303,7 +6399,9 @@ private SequencedMap map() { public void addFirst(E e) { map().putFirst(e, Boolean.TRUE); } public void addLast(E e) { map().putLast(e, Boolean.TRUE); } + @Pure public E getFirst() { return nsee(map().firstEntry()); } + @Pure public E getLast() { return nsee(map().lastEntry()); } public E removeFirst() { return nsee(map().pollFirstEntry()); } public E removeLast() { return nsee(map().pollLastEntry()); } @@ -6335,7 +6433,7 @@ private SequencedMap map() { * @return the queue * @since 1.6 */ - public static @PolyModifiable @PolyGrowShrink @PolyNonEmpty Queue asLifoQueue(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Deque deque) { + public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Queue asLifoQueue(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Deque deque) { return new AsLIFOQueue<>(Objects.requireNonNull(deque)); } @@ -6373,6 +6471,7 @@ static class AsLIFOQueue extends AbstractQueue public @PolyNull @PolySigned Object[] toArray(Collections.AsLIFOQueue<@PolyNull @PolySigned E> this) { return q.toArray(); } @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return q.toArray(a); } + @SideEffectFree public T[] toArray(IntFunction f) { return q.toArray(f); } public String toString() { return q.toString(); } @Pure diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index b28d09550095..44b5dd360984 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -39,8 +39,8 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -48,6 +48,7 @@ import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -240,6 +241,7 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") void addFirst(@Growable @GuardSatisfied Deque this, E e); /** @@ -262,6 +264,7 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") void addLast(@Growable @GuardSatisfied Deque this, E e); /** @@ -280,6 +283,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + @DoesNotUnrefineReceiver("modifiability") boolean offerFirst(@Growable Deque this, E e); /** @@ -298,6 +302,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + @DoesNotUnrefineReceiver("modifiability") boolean offerLast(@Growable Deque this, E e); /** @@ -308,6 +313,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -318,6 +324,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the tail of this deque * @throws NoSuchElementException if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -326,6 +333,7 @@ public interface Deque extends Queue, SequencedCollection { * * @return the head of this deque, or {@code null} if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink Deque this); /** @@ -334,6 +342,7 @@ public interface Deque extends Queue, SequencedCollection { * * @return the tail of this deque, or {@code null} if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink Deque this); /** @@ -346,6 +355,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws NoSuchElementException if this deque is empty */ @EnsuresNonEmpty("this") + @Pure E getFirst(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -357,6 +367,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws NoSuchElementException if this deque is empty */ @EnsuresNonEmpty("this") + @Pure E getLast(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -365,6 +376,7 @@ public interface Deque extends Queue, SequencedCollection { * * @return the head of this deque, or {@code null} if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E peekFirst(); /** @@ -373,6 +385,7 @@ public interface Deque extends Queue, SequencedCollection { * * @return the tail of this deque, or {@code null} if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E peekLast(); /** @@ -392,6 +405,7 @@ public interface Deque extends Queue, SequencedCollection { * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ + @DoesNotUnrefineReceiver("modifiability") boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink Deque this, Object o); /** @@ -411,6 +425,7 @@ public interface Deque extends Queue, SequencedCollection { * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ + @DoesNotUnrefineReceiver("modifiability") boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Deque this, Object o); // *** Queue methods *** @@ -438,6 +453,7 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(@Growable @GuardSatisfied Deque this, E e); /** @@ -461,6 +477,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + @DoesNotUnrefineReceiver("modifiability") boolean offer(@Growable Deque this, E e); /** @@ -474,6 +491,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -486,6 +504,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the first element of this deque, or {@code null} if * this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink Deque this); /** @@ -499,6 +518,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") E element(@GuardSatisfied @NonEmpty Deque this); /** @@ -511,6 +531,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of the queue represented by this deque, or * {@code null} if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E peek(); /** @@ -537,6 +558,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of an element of the * specified collection prevents it from being added to this deque */ + @DoesNotUnrefineReceiver("modifiability") boolean addAll(@Growable Deque this, Collection c); // *** Stack methods *** @@ -559,6 +581,7 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + @DoesNotUnrefineReceiver("modifiability") void push(@Growable @GuardSatisfied Deque this, E e); /** @@ -571,6 +594,7 @@ public interface Deque extends Queue, SequencedCollection { * of the stack represented by this deque) * @throws NoSuchElementException if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Deque this); @@ -595,6 +619,7 @@ public interface Deque extends Queue, SequencedCollection { * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ + @DoesNotUnrefineReceiver("modifiability") boolean remove(@Shrinkable @GuardSatisfied @CanShrink Deque this, @UnknownSignedness Object o); /** @@ -640,6 +665,7 @@ public interface Deque extends Queue, SequencedCollection { * @return an iterator over the elements in this deque in reverse * sequence */ + @DoesNotUnrefineReceiver("modifiability") Iterator descendingIterator(); /** @@ -652,6 +678,7 @@ public interface Deque extends Queue, SequencedCollection { * @return a reverse-ordered view of this collection, as a {@code Deque} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default Deque reversed() { return ReverseOrderDequeView.of(this); } diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index b02d5e6e6c13..de0ab5531847 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -542,7 +542,6 @@ public Object[] toArray() { } @CFComment({"nullness: 'a' is known to be of array class type", "Annotation for toArray are technically incorrect. Refer to note on toArray in Collection.java"}) - @SideEffectFree @SuppressWarnings({ "unchecked", "nullness:argument", diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index bb0d6f2085f2..24ea615d8451 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.framework.qual.AnnotatedFor; import jdk.internal.access.SharedSecrets; @@ -147,6 +148,7 @@ public abstract sealed class EnumSet> extends AbstractSet * Adds all of the elements from the appropriate enum type to this enum * set, which is empty prior to the call. */ + @DoesNotUnrefineReceiver("modifiability") abstract void addAll(@Growable EnumSet this); /** @@ -378,6 +380,7 @@ public abstract sealed class EnumSet> extends AbstractSet * Adds the specified range to this enum set, which is empty prior * to the call. */ + @DoesNotUnrefineReceiver("modifiability") abstract void addRange(@Growable EnumSet this, E from, E to); /** @@ -386,6 +389,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return a copy of this set */ @SuppressWarnings("unchecked") + @DoesNotUnrefineReceiver("modifiability") public @Modifiable EnumSet clone() { try { return (EnumSet) super.clone(); @@ -397,6 +401,7 @@ public abstract sealed class EnumSet> extends AbstractSet /** * Complements the contents of this enum set. */ + @DoesNotUnrefineReceiver("modifiability") abstract void complement(@Growable @Shrinkable EnumSet this); /** diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 103af8a27a01..6a34e75f4381 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -27,14 +27,14 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -45,6 +45,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -326,6 +327,7 @@ public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } + @DoesNotUnrefineReceiver("modifiability") public final V setValue(V newValue) { V oldValue = value; value = newValue; @@ -648,6 +650,7 @@ public boolean containsKey(@GuardSatisfied HashMap this, @GuardSatisfied @ * previously associated {@code null} with {@code key}.) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@Growable @Replaceable @GuardSatisfied HashMap this, K key, V value) { return putVal(hash(key), key, value, false, true); } @@ -822,6 +825,7 @@ else if ((e = tab[index = (n - 1) & hash]) != null) { * @param m mappings to be stored in this map * @throws NullPointerException if the specified map is null */ + @DoesNotUnrefineReceiver("modifiability") public void putAll(@Growable @Replaceable @GuardSatisfied HashMap this, Map m) { putMapEntries(m, true); } @@ -835,6 +839,7 @@ public void putAll(@Growable @Replaceable @GuardSatisfied HashMap this, Ma * (A {@code null} return can also indicate that the map * previously associated {@code null} with {@code key}.) */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable V remove(@Shrinkable @GuardSatisfied HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Node e; return (e = removeNode(hash(key), key, null, false, true)) == null ? @@ -896,6 +901,7 @@ else if (node == p) * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied HashMap this) { Node[] tab; modCount++; @@ -1025,12 +1031,14 @@ T[] valuesToArray(T[] a) { final @Shrinkable class KeySet extends AbstractSet { @Pure public final @NonNegative int size() { return size; } + @DoesNotUnrefineReceiver("modifiability") public final void clear() { HashMap.this.clear(); } @SideEffectFree public final @Modifiable Iterator iterator() { return new KeyIterator(); } @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public final boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object key) { return removeNode(hash(key), key, null, false, true) != null; } @@ -1039,6 +1047,7 @@ public final Spliterator spliterator() { return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0); } + @SideEffectFree public Object[] toArray() { return keysToArray(new Object[size]); } @@ -1047,6 +1056,7 @@ public Object[] toArray() { return keysToArray(prepareArray(a)); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer action) { Node[] tab; if (action == null) @@ -1091,6 +1101,7 @@ public final void forEach(Consumer action) { final @Shrinkable class Values extends AbstractCollection { @Pure public final @NonNegative int size() { return size; } + @DoesNotUnrefineReceiver("modifiability") public final void clear() { HashMap.this.clear(); } @SideEffectFree public final @Modifiable Iterator iterator() { return new ValueIterator(); } @@ -1102,6 +1113,7 @@ public final Spliterator spliterator() { return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0); } + @SideEffectFree public Object[] toArray() { return valuesToArray(new Object[size]); } @@ -1151,6 +1163,7 @@ public final void forEach(Consumer action) { final @Shrinkable class EntrySet extends AbstractSet> { @Pure public final @NonNegative int size() { return size; } + @DoesNotUnrefineReceiver("modifiability") public final void clear() { HashMap.this.clear(); } @SideEffectFree public final @Modifiable Iterator> iterator() { @@ -1165,6 +1178,7 @@ public final boolean contains(@Nullable @UnknownSignedness Object o) { Node candidate = getNode(key); return candidate != null && candidate.equals(e); } + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object o) { if (o instanceof Map.Entry e) { Object key = e.getKey(); @@ -1177,6 +1191,7 @@ public final boolean remove(@Nullable @UnknownSignedness Object o) { public final Spliterator> spliterator() { return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer> action) { Node[] tab; if (action == null) @@ -1204,16 +1219,19 @@ public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override + @DoesNotUnrefineReceiver("modifiability") public @Nullable V putIfAbsent(@Growable HashMap this, K key, V value) { return putVal(hash(key), key, value, true, true); } @Override + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return removeNode(hash(key), key, value, true, true) != null; } @Override + @DoesNotUnrefineReceiver("modifiability") public boolean replace(@Replaceable HashMap this, K key, V oldValue, V newValue) { Node e; V v; if ((e = getNode(key)) != null && @@ -1226,6 +1244,7 @@ public boolean replace(@Replaceable HashMap this, K key, V oldValue, V newV } @Override + @DoesNotUnrefineReceiver("modifiability") public @Nullable V replace(@Replaceable HashMap this, K key, V value) { Node e; if ((e = getNode(key)) != null) { @@ -1248,6 +1267,7 @@ public boolean replace(@Replaceable HashMap this, K key, V oldValue, V newV * mapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(@Growable HashMap this, K key, Function mappingFunction) { if (mappingFunction == null) @@ -1314,6 +1334,7 @@ else if (t != null) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(@Shrinkable @Replaceable HashMap this, K key, BiFunction remappingFunction) { if (remappingFunction == null) @@ -1348,6 +1369,7 @@ else if (t != null) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(@Modifiable HashMap this, K key, BiFunction remappingFunction) { if (remappingFunction == null) @@ -1413,6 +1435,7 @@ else if (v != null) { * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(@Modifiable HashMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (value == null || remappingFunction == null) @@ -1474,6 +1497,7 @@ else if (v != null) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { Node[] tab; if (action == null) @@ -1490,6 +1514,7 @@ public void forEach(BiConsumer action) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable HashMap this, BiFunction function) { Node[] tab; if (function == null) @@ -1671,6 +1696,7 @@ final Node nextNode(@NonEmpty HashIterator this) { return e; } + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node p = current; if (p == null) @@ -1685,16 +1711,19 @@ public final void remove() { final @Modifiable class KeyIterator extends HashIterator implements Iterator { + @DoesNotUnrefineReceiver("modifiability") public final K next(@NonEmpty KeyIterator this) { return nextNode().key; } } final @Modifiable class ValueIterator extends HashIterator implements Iterator { + @DoesNotUnrefineReceiver("modifiability") public final V next(@NonEmpty ValueIterator this) { return nextNode().value; } } final @Modifiable class EntryIterator extends HashIterator implements Iterator> { + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry next(@NonEmpty EntryIterator this) { return nextNode(); } } diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index f083d281b427..41244751b32c 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -29,8 +29,6 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -42,6 +40,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -202,7 +201,7 @@ public class HashSet * @see ConcurrentModificationException */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty HashSet this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty HashSet this) { return map.keySet().iterator(); } @@ -401,11 +400,13 @@ private void readObject(java.io.ObjectInputStream s) * @return a {@code Spliterator} over the elements in this set * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public Spliterator spliterator() { return new HashMap.KeySpliterator<>(map, 0, -1, 0, 0); } @Override + @SideEffectFree public Object[] toArray() { return map.keysToArray(new Object[map.size()]); } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index aecededa6607..47c988c88d5c 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -43,6 +43,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -506,6 +507,7 @@ private void addEntry(int hash, K key, V value, int index) { * @see #get(Object) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable V put(@Growable @Replaceable @GuardSatisfied Hashtable this, K key, V value) { // Make sure the value is not null if (value == null) { @@ -539,6 +541,7 @@ private void addEntry(int hash, K key, V value, int index) { * or {@code null} if the key did not have a mapping * @throws NullPointerException if the key is {@code null} */ + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable V remove(@Shrinkable @GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { Entry tab[] = table; int hash = key.hashCode(); @@ -571,6 +574,7 @@ private void addEntry(int hash, K key, V value, int index) { * @throws NullPointerException if the specified map is null * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable this, Map t) { for (Map.Entry e : t.entrySet()) put(e.getKey(), e.getValue()); @@ -579,6 +583,7 @@ public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable /** * Clears this hashtable so that it contains no keys. */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) { Entry tab[] = table; for (int index = tab.length; --index >= 0; ) @@ -716,9 +721,11 @@ public Iterator iterator() { public boolean contains(@UnknownSignedness Object o) { return containsKey(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { return Hashtable.this.remove(o) != null; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { Hashtable.this.clear(); } @@ -754,6 +761,7 @@ public Iterator> iterator() { } @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(Map.Entry o) { return super.add(o); } @@ -774,6 +782,7 @@ public boolean contains(@UnknownSignedness Object o) { return false; } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry entry)) return false; @@ -805,6 +814,7 @@ public boolean remove(@UnknownSignedness Object o) { return count; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { Hashtable.this.clear(); } @@ -847,6 +857,7 @@ public Iterator iterator() { public boolean contains(@UnknownSignedness Object o) { return containsValue(o); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { Hashtable.this.clear(); } @@ -938,6 +949,7 @@ public synchronized V getOrDefault(@GuardSatisfied @UnknownSignedness Object key @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void forEach(BiConsumer action) { Objects.requireNonNull(action); // explicit check required in case // table is empty. @@ -958,6 +970,7 @@ public synchronized void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(@Replaceable Hashtable this, BiFunction function) { Objects.requireNonNull(function); // explicit check required in case // table is empty. @@ -979,6 +992,7 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized V putIfAbsent(@Growable Hashtable this, K key, V value) { Objects.requireNonNull(value); @@ -1003,6 +1017,7 @@ public synchronized V putIfAbsent(@Growable Hashtable this, K key, V value } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Objects.requireNonNull(value); @@ -1028,6 +1043,7 @@ public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatis } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean replace(@Replaceable Hashtable this, K key, V oldValue, V newValue) { Objects.requireNonNull(oldValue); Objects.requireNonNull(newValue); @@ -1050,6 +1066,7 @@ public synchronized boolean replace(@Replaceable Hashtable this, K key, V } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized V replace(@Replaceable Hashtable this, K key, V value) { Objects.requireNonNull(value); Entry tab[] = table; @@ -1078,6 +1095,7 @@ public synchronized V replace(@Replaceable Hashtable this, K key, V value) * mapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V computeIfAbsent(@Growable Hashtable this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -1114,6 +1132,7 @@ public synchronized V replace(@Replaceable Hashtable this, K key, V value) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V computeIfPresent(@Shrinkable @Replaceable Hashtable this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1156,6 +1175,7 @@ public synchronized V replace(@Replaceable Hashtable this, K key, V value) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V compute(@Modifiable Hashtable this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1207,6 +1227,7 @@ public synchronized V replace(@Replaceable Hashtable this, K key, V value) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V merge(@Modifiable Hashtable this, K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1443,14 +1464,17 @@ protected Object clone() { // Map.Entry Ops + @Pure public K getKey() { return key; } + @Pure public V getValue() { return value; } + @DoesNotUnrefineReceiver("modifiability") public V setValue(V value) { if (value == null) throw new NullPointerException(); @@ -1460,6 +1484,7 @@ public V setValue(V value) { return oldValue; } + @Pure public boolean equals(Object o) { if (!(o instanceof Map.Entry e)) return false; @@ -1468,6 +1493,7 @@ public boolean equals(Object o) { (value==null ? e.getValue()==null : value.equals(e.getValue())); } + @Pure public int hashCode() { return hash ^ Objects.hashCode(value); } @@ -1561,6 +1587,7 @@ public T next(@NonEmpty Enumerator this) { return nextElement(); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (!iterator) throw new UnsupportedOperationException(); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 1a48ce607ba1..5a14c6a4dfe5 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -29,8 +29,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -41,6 +41,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -463,6 +464,7 @@ private boolean containsMapping(@UnknownSignedness @GuardSatisfied @Nullable Obj * @see #containsKey(Object) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, K key, V value) { final Object k = maskNull(key); @@ -544,6 +546,7 @@ private boolean resize(int newCapacity) { * @param m mappings to be stored in this map * @throws NullPointerException if the specified map is null */ + @DoesNotUnrefineReceiver("modifiability") public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, Map m) { int n = m.size(); if (n == 0) @@ -566,6 +569,7 @@ public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap * (A {@code null} return can also indicate that the map * previously associated {@code null} with {@code key}.) */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable V remove(@Shrinkable @GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); Object[] tab = table; @@ -662,6 +666,7 @@ private void closeDeletion(int d) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied IdentityHashMap this) { modCount++; Object[] tab = table; @@ -801,6 +806,7 @@ protected int nextIndex(@NonEmpty IdentityHashMapIterator this) { return lastReturnedIndex; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturnedIndex == -1) throw new IllegalStateException(); @@ -903,6 +909,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { return lastReturnedEntry; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { lastReturnedIndex = ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index); @@ -919,18 +926,21 @@ private Entry(int index) { } @SuppressWarnings("unchecked") + @Pure public K getKey() { checkIndexForEntryUse(); return (K) unmaskNull(traversalTable[index]); } @SuppressWarnings("unchecked") + @Pure public V getValue() { checkIndexForEntryUse(); return (V) traversalTable[index+1]; } @SuppressWarnings("unchecked") + @DoesNotUnrefineReceiver("modifiability") public V setValue(V value) { checkIndexForEntryUse(); V oldValue = (V) traversalTable[index+1]; @@ -941,6 +951,7 @@ public V setValue(V value) { return oldValue; } + @Pure public boolean equals(@Nullable Object o) { if (index < 0) return super.equals(o); @@ -950,6 +961,7 @@ public boolean equals(@Nullable Object o) { && e.getValue() == traversalTable[index+1]; } + @Pure public int hashCode() { if (lastReturnedIndex < 0) return super.hashCode(); @@ -1044,6 +1056,7 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { int oldSize = size; IdentityHashMap.this.remove(o); @@ -1054,6 +1067,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { * the former contains an optimization that results in incorrect * behavior when c is a smaller "normal" (non-identity-based) Set. */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -1065,6 +1079,7 @@ public boolean removeAll(Collection c) { } return modified; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { IdentityHashMap.this.clear(); } @@ -1079,7 +1094,6 @@ public Object[] toArray() { return toArray(new Object[0]); } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { int expectedModCount = modCount; int size = size(); @@ -1158,6 +1172,7 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { for (Iterator i = iterator(); i.hasNext(); ) { if (i.next() == o) { @@ -1167,6 +1182,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { } return false; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { IdentityHashMap.this.clear(); } @@ -1175,7 +1191,6 @@ public Object[] toArray() { return toArray(new Object[0]); } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { int expectedModCount = modCount; int size = size(); @@ -1269,6 +1284,7 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return o instanceof Entry entry && containsMapping(entry.getKey(), entry.getValue()); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { return o instanceof Entry entry && removeMapping(entry.getKey(), entry.getValue()); @@ -1277,6 +1293,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { public @NonNegative int size() { return size; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { IdentityHashMap.this.clear(); } @@ -1285,6 +1302,7 @@ public void clear() { * the former contains an optimization that results in incorrect * behavior when c is a smaller "normal" (non-identity-based) Set. */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -1303,7 +1321,6 @@ public Object[] toArray() { } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { int expectedModCount = modCount; int size = size(); diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java index 293e8c224488..f13c483463f4 100644 --- a/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -405,6 +405,7 @@ public void remove() { throw uoe(); } + @Pure public boolean hasPrevious() { if (!isListIterator) { throw uoe(); @@ -483,6 +484,7 @@ static SubList fromList(AbstractImmutableList list, int fromIndex, int return new SubList<>(list, fromIndex, toIndex - fromIndex); } + @Pure public E get(int index) { Objects.checkIndex(index, size); return root.get(offset + index); @@ -518,6 +520,8 @@ private boolean allowNulls() { } @Override + @Pure + @StaticallyExecutable public int indexOf(Object o) { if (!allowNulls() && o == null) { throw new NullPointerException(); @@ -531,6 +535,8 @@ public int indexOf(Object o) { } @Override + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { if (!allowNulls() && o == null) { throw new NullPointerException(); @@ -544,6 +550,7 @@ public int lastIndexOf(Object o) { } @Override + @SideEffectFree public Object[] toArray() { Object[] array = new Object[size]; for (int i = 0; i < size; i++) { @@ -603,6 +610,7 @@ public boolean isEmpty() { } @Override + @Pure @SuppressWarnings("unchecked") public E get(int index) { if (index == 0) { @@ -614,6 +622,8 @@ public E get(int index) { } @Override + @Pure + @StaticallyExecutable public int indexOf(Object o) { Objects.requireNonNull(o); if (o.equals(e0)) { @@ -626,6 +636,8 @@ public int indexOf(Object o) { } @Override + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { Objects.requireNonNull(o); if (e1 != EMPTY && o.equals(e1)) { @@ -652,6 +664,7 @@ private Object writeReplace() { } @Override + @SideEffectFree public Object[] toArray() { if (e1 == EMPTY) { return new Object[] { e0 }; @@ -707,6 +720,7 @@ public int size() { } @Override + @Pure public E get(int index) { return elements[index]; } @@ -722,6 +736,7 @@ private Object writeReplace() { } @Override + @SideEffectFree public Object[] toArray() { return Arrays.copyOf(elements, elements.length); } @@ -742,6 +757,8 @@ public Object[] toArray() { } @Override + @Pure + @StaticallyExecutable public int indexOf(Object o) { if (!allowNulls && o == null) { throw new NullPointerException(); @@ -756,6 +773,8 @@ public int indexOf(Object o) { } @Override + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { if (!allowNulls && o == null) { throw new NullPointerException(); @@ -894,6 +913,7 @@ private Object writeReplace() { } @Override + @SideEffectFree public Object[] toArray() { if (e1 == EMPTY) { return new Object[] { e0 }; @@ -1080,6 +1100,7 @@ private Object writeReplace() { } @Override + @SideEffectFree public Object[] toArray() { Object[] array = new Object[size]; Iterator it = iterator(); diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index 1d8786ebe8dc..b767443e391c 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -90,6 +91,7 @@ public interface Iterator { * @throws NoSuchElementException if the iteration has no more elements */ @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E next(@GuardSatisfied @NonEmpty Iterator this); /** @@ -117,6 +119,7 @@ public interface Iterator { * been called after the last call to the {@code next} * method */ + @DoesNotUnrefineReceiver("modifiability") default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { throw new UnsupportedOperationException("remove"); } @@ -146,6 +149,7 @@ default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { * @throws NullPointerException if the specified action is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { Objects.requireNonNull(action); while (hasNext()) diff --git a/src/java.base/share/classes/java/util/JumboEnumSet.java b/src/java.base/share/classes/java/util/JumboEnumSet.java index 6005a4c5bd0a..72dc66eb2072 100644 --- a/src/java.base/share/classes/java/util/JumboEnumSet.java +++ b/src/java.base/share/classes/java/util/JumboEnumSet.java @@ -35,6 +35,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -71,6 +72,7 @@ final class JumboEnumSet> extends EnumSet { elements = new long[(universe.length + 63) >>> 6]; } + @DoesNotUnrefineReceiver("modifiability") void addRange(E from, E to) { int fromIndex = from.ordinal() >>> 6; int toIndex = to.ordinal() >>> 6; @@ -87,6 +89,7 @@ void addRange(E from, E to) { size = to.ordinal() - from.ordinal() + 1; } + @DoesNotUnrefineReceiver("modifiability") void addAll() { for (int i = 0; i < elements.length; i++) elements[i] = -1; @@ -94,6 +97,7 @@ void addAll() { size = universe.length; } + @DoesNotUnrefineReceiver("modifiability") void complement() { for (int i = 0; i < elements.length; i++) elements[i] = ~elements[i]; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 34f72f2b77d2..e1839a80ab4a 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -29,8 +29,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -40,6 +40,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -410,6 +411,7 @@ void afterNodeAccess(Node e) { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { try { putMode = PUT_FIRST; @@ -427,6 +429,7 @@ public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public V putLast(@Growable @Replaceable LinkedHashMap this, K k, V v) { try { putMode = PUT_LAST; @@ -579,6 +582,7 @@ public V getOrDefault(@Nullable Object key, V defaultValue) { /** * {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied LinkedHashMap this) { super.clear(); head = tail = null; @@ -721,6 +725,7 @@ final class LinkedKeySet extends AbstractSet implements SequencedSet { LinkedKeySet(boolean reversed) { this.reversed = reversed; } @Pure public final int size() { return size; } + @DoesNotUnrefineReceiver("modifiability") public final void clear() { LinkedHashMap.this.clear(); } @SideEffectFree public final @Modifiable Iterator iterator() { @@ -729,6 +734,7 @@ final class LinkedKeySet extends AbstractSet implements SequencedSet { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public final boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object key) { return removeNode(hash(key), key, null, false, true) != null; } @@ -739,6 +745,7 @@ public final Spliterator spliterator() { Spliterator.DISTINCT); } + @SideEffectFree public Object[] toArray() { return keysToArray(new Object[size], reversed); } @@ -747,6 +754,7 @@ public Object[] toArray() { return keysToArray(prepareArray(a), reversed); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer action) { if (action == null) throw new NullPointerException(); @@ -765,11 +773,13 @@ public final void forEach(Consumer action) { public final void addLast(K k) { throw new UnsupportedOperationException(); } public final K getFirst() { return nsee(reversed ? tail : head).key; } public final K getLast() { return nsee(reversed ? head : tail).key; } + @DoesNotUnrefineReceiver("modifiability") public final K removeFirst() { var node = nsee(reversed ? tail : head); removeNode(node.hash, node.key, null, false, false); return node.key; } + @DoesNotUnrefineReceiver("modifiability") public final K removeLast() { var node = nsee(reversed ? head : tail); removeNode(node.hash, node.key, null, false, false); @@ -848,6 +858,7 @@ public final Spliterator spliterator() { Spliterator.ORDERED); } + @SideEffectFree public Object[] toArray() { return valuesToArray(new Object[size], reversed); } @@ -856,6 +867,7 @@ public Object[] toArray() { return valuesToArray(prepareArray(a), reversed); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer action) { if (action == null) throw new NullPointerException(); @@ -874,11 +886,13 @@ public final void forEach(Consumer action) { public final void addLast(V v) { throw new UnsupportedOperationException(); } public final V getFirst() { return nsee(reversed ? tail : head).value; } public final V getLast() { return nsee(reversed ? head : tail).value; } + @DoesNotUnrefineReceiver("modifiability") public final V removeFirst() { var node = nsee(reversed ? tail : head); removeNode(node.hash, node.key, null, false, false); return node.value; } + @DoesNotUnrefineReceiver("modifiability") public final V removeLast() { var node = nsee(reversed ? head : tail); removeNode(node.hash, node.key, null, false, false); @@ -960,6 +974,7 @@ public final boolean contains(@Nullable @UnknownSignedness Object o) { Node candidate = getNode(key); return candidate != null && candidate.equals(e); } + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object o) { if (o instanceof Map.Entry e) { Object key = e.getKey(); @@ -974,6 +989,7 @@ public final Spliterator> spliterator() { Spliterator.ORDERED | Spliterator.DISTINCT); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer> action) { if (action == null) throw new NullPointerException(); @@ -998,11 +1014,13 @@ final Node nsee(Node e) { public final void addLast(Map.Entry e) { throw new UnsupportedOperationException(); } public final Map.Entry getFirst() { return nsee(reversed ? tail : head); } public final Map.Entry getLast() { return nsee(reversed ? head : tail); } + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry removeFirst() { var node = nsee(reversed ? tail : head); removeNode(node.hash, node.key, null, false, false); return node; } + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry removeLast() { var node = nsee(reversed ? head : tail); removeNode(node.hash, node.key, null, false, false); @@ -1019,6 +1037,7 @@ public SequencedSet> reversed() { // Map overrides + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); @@ -1029,6 +1048,7 @@ public void forEach(BiConsumer action) { throw new ConcurrentModificationException(); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable LinkedHashMap this, BiFunction function) { if (function == null) throw new NullPointerException(); @@ -1072,6 +1092,7 @@ final LinkedHashMap.Entry nextNode(@NonEmpty LinkedHashIterator this) { return e; } + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node p = current; if (p == null) @@ -1149,48 +1170,59 @@ static class ReversedLinkedHashMapView extends AbstractMap // Object // inherit toString() from AbstractMap; it depends on entrySet() + @Pure public boolean equals(Object o) { return base.equals(o); } + @Pure public int hashCode() { return base.hashCode(); } // Map + @Pure public int size() { return base.size(); } + @Pure public boolean isEmpty() { return base.isEmpty(); } + @Pure public boolean containsKey(Object key) { return base.containsKey(key); } + @Pure public boolean containsValue(Object value) { return base.containsValue(value); } + @Pure public V get(Object key) { return base.get(key); } + @DoesNotUnrefineReceiver("modifiability") public V put(@Growable @Replaceable ReversedLinkedHashMapView this, K key, V value) { return base.put(key, value); } + @DoesNotUnrefineReceiver("modifiability") public V remove(@Shrinkable ReversedLinkedHashMapView this, Object key) { return base.remove(key); } + @DoesNotUnrefineReceiver("modifiability") public void putAll(@Growable @Replaceable ReversedLinkedHashMapView this, Map m) { base.putAll(m); } + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } @@ -1207,10 +1239,12 @@ public Set> entrySet() { return base.sequencedEntrySet().reversed(); } + @Pure public V getOrDefault(Object key, V defaultValue) { return base.getOrDefault(key, defaultValue); } + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); @@ -1221,6 +1255,7 @@ public void forEach(BiConsumer action) { throw new ConcurrentModificationException(); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable ReversedLinkedHashMapView this, BiFunction function) { if (function == null) throw new NullPointerException(); @@ -1231,34 +1266,42 @@ public void replaceAll(@Replaceable ReversedLinkedHashMapView this, BiFunct throw new ConcurrentModificationException(); } + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(@Growable ReversedLinkedHashMapView this, K key, V value) { return base.putIfAbsent(key, value); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable ReversedLinkedHashMapView this, Object key, Object value) { return base.remove(key, value); } + @DoesNotUnrefineReceiver("modifiability") public boolean replace(@Replaceable ReversedLinkedHashMapView this, K key, V oldValue, V newValue) { return base.replace(key, oldValue, newValue); } + @DoesNotUnrefineReceiver("modifiability") public V replace(@Replaceable ReversedLinkedHashMapView this, K key, V value) { return base.replace(key, value); } + @DoesNotUnrefineReceiver("modifiability") public V computeIfAbsent(@Growable ReversedLinkedHashMapView this, K key, Function mappingFunction) { return base.computeIfAbsent(key, mappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V computeIfPresent(@Shrinkable @Replaceable ReversedLinkedHashMapView this, K key, BiFunction remappingFunction) { return base.computeIfPresent(key, remappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V compute(@Modifiable ReversedLinkedHashMapView this, K key, BiFunction remappingFunction) { return base.compute(key, remappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V merge(@Modifiable ReversedLinkedHashMapView this, K key, V value, BiFunction remappingFunction) { return base.merge(key, value, remappingFunction); } @@ -1269,26 +1312,32 @@ public SequencedMap reversed() { return base; } + @Pure public Entry firstEntry() { return base.lastEntry(); } + @Pure public Entry lastEntry() { return base.firstEntry(); } + @DoesNotUnrefineReceiver("modifiability") public Entry pollFirstEntry(@Shrinkable ReversedLinkedHashMapView this) { return base.pollLastEntry(); } + @DoesNotUnrefineReceiver("modifiability") public Entry pollLastEntry(@Shrinkable ReversedLinkedHashMapView this) { return base.pollFirstEntry(); } + @DoesNotUnrefineReceiver("modifiability") public V putFirst(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { return base.putLast(k, v); } + @DoesNotUnrefineReceiver("modifiability") public V putLast(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { return base.putFirst(k, v); } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 13b934ca653b..dd2723084ab5 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -213,6 +214,7 @@ public class LinkedHashSet * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED); } @@ -237,6 +239,7 @@ public static LinkedHashSet newLinkedHashSet(int numElements) { } @SuppressWarnings("unchecked") + @Deterministic LinkedHashMap map() { return (LinkedHashMap) map; } @@ -249,6 +252,7 @@ LinkedHashMap map() { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable LinkedHashSet this, E e) { map().putFirst(e, PRESENT); } @@ -261,6 +265,7 @@ public void addFirst(@Growable LinkedHashSet this, E e) { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable LinkedHashSet this, E e) { map().putLast(e, PRESENT); } @@ -271,6 +276,7 @@ public void addLast(@Growable LinkedHashSet this, E e) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getFirst() { return map().sequencedKeySet().getFirst(); } @@ -281,6 +287,7 @@ public E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getLast() { return map().sequencedKeySet().getLast(); } @@ -291,6 +298,7 @@ public E getLast() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable LinkedHashSet this) { return map().sequencedKeySet().removeFirst(); } @@ -301,6 +309,7 @@ public E removeFirst(@Shrinkable LinkedHashSet this) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable LinkedHashSet this) { return map().sequencedKeySet().removeLast(); } @@ -314,6 +323,7 @@ public E removeLast(@Shrinkable LinkedHashSet this) { * @return {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public SequencedSet reversed() { class ReverseLinkedHashSetView extends AbstractSet implements SequencedSet { public int size() { return LinkedHashSet.this.size(); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index cd3cfcc83dfe..a45acc91c49a 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -44,6 +44,8 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -276,6 +278,7 @@ E unlink(Node x) { * @return the first element in this list * @throws NoSuchElementException if this list is empty */ + @Pure public E getFirst(@GuardSatisfied @NonEmpty LinkedList this) { final Node f = first; if (f == null) @@ -289,6 +292,7 @@ public E getFirst(@GuardSatisfied @NonEmpty LinkedList this) { * @return the last element in this list * @throws NoSuchElementException if this list is empty */ + @Pure public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { final Node l = last; if (l == null) @@ -302,6 +306,7 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { * @return the first element from this list * @throws NoSuchElementException if this list is empty */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node f = first; if (f == null) @@ -315,6 +320,7 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList * @return the last element from this list * @throws NoSuchElementException if this list is empty */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node l = last; if (l == null) @@ -327,6 +333,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList< * * @param e the element to add */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { linkFirst(e); } @@ -338,6 +345,7 @@ public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { * * @param e the element to add */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable @GuardSatisfied LinkedList this, E e) { linkLast(e); } @@ -377,6 +385,7 @@ public boolean contains(@GuardSatisfied LinkedList this, @GuardSatisfied @Nul */ @ReleasesNoLocks @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable @GuardSatisfied LinkedList this, E e) { linkLast(e); return true; @@ -396,6 +405,7 @@ public boolean add(@Growable @GuardSatisfied LinkedList this, E e) { * @return {@code true} if this list contained the specified element */ @ReleasesNoLocks + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { for (Node x = first; x != null; x = x.next) { @@ -427,6 +437,7 @@ public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, * @return {@code true} if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable @GuardSatisfied LinkedList this, Collection c) { return addAll(size, c); } @@ -446,6 +457,7 @@ public boolean addAll(@Growable @GuardSatisfied LinkedList this, Collection this, @NonNegative int index, Collection c) { checkPositionIndex(index); @@ -489,6 +501,7 @@ public boolean addAll(@Growable @GuardSatisfied LinkedList this, @NonNegative * Removes all of the elements from this list. * The list will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit @@ -531,6 +544,7 @@ public E get(@GuardSatisfied LinkedList this, @NonNegative int index) { * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E set(@Replaceable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkElementIndex(index); Node x = node(index); @@ -548,6 +562,7 @@ public E set(@Replaceable @GuardSatisfied LinkedList this, @NonNegative int i * @param element element to be inserted * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void add(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkPositionIndex(index); @@ -566,6 +581,7 @@ public void add(@Growable @GuardSatisfied LinkedList this, @NonNegative int i * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @NonNegative int index) { checkElementIndex(index); return unlink(node(index)); @@ -638,6 +654,7 @@ Node node(@NonNegative int index) { * this list, or -1 if this list does not contain the element */ @Pure + @StaticallyExecutable public @GTENegativeOne int indexOf(@GuardSatisfied LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { int index = 0; if (o == null) { @@ -668,6 +685,7 @@ Node node(@NonNegative int index) { * this list, or -1 if this list does not contain the element */ @Pure + @StaticallyExecutable public @GTENegativeOne int lastIndexOf(@GuardSatisfied LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { int index = size; if (o == null) { @@ -707,6 +725,7 @@ Node node(@NonNegative int index) { * @throws NoSuchElementException if this list is empty * @since 1.5 */ + @SideEffectFree public E element(@GuardSatisfied @NonEmpty LinkedList this) { return getFirst(); } @@ -717,6 +736,7 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { * @return the head of this list, or {@code null} if this list is empty * @since 1.5 */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node f = first; return (f == null) ? null : unlinkFirst(f); @@ -729,6 +749,7 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { * @throws NoSuchElementException if this list is empty * @since 1.5 */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); } @@ -740,6 +761,7 @@ public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList t * @return {@code true} (as specified by {@link Queue#offer}) * @since 1.5 */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedList this, E e) { return add(e); } @@ -752,6 +774,7 @@ public boolean offer(@Growable LinkedList this, E e) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(@Growable LinkedList this, E e) { addFirst(e); return true; @@ -764,6 +787,7 @@ public boolean offerFirst(@Growable LinkedList this, E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(@Growable LinkedList this, E e) { addLast(e); return true; @@ -805,6 +829,7 @@ public boolean offerLast(@Growable LinkedList this, E e) { * this list is empty * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node f = first; return (f == null) ? null : unlinkFirst(f); @@ -818,6 +843,7 @@ public boolean offerLast(@Growable LinkedList this, E e) { * this list is empty * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node l = last; return (l == null) ? null : unlinkLast(l); @@ -832,6 +858,7 @@ public boolean offerLast(@Growable LinkedList this, E e) { * @param e the element to push * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public void push(@Growable @GuardSatisfied LinkedList this, E e) { addFirst(e); } @@ -847,6 +874,7 @@ public void push(@Growable @GuardSatisfied LinkedList this, E e) { * @throws NoSuchElementException if this list is empty * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); } @@ -860,6 +888,7 @@ public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this * @return {@code true} if the list contained the specified element * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return remove(o); } @@ -873,6 +902,7 @@ public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink Link * @return {@code true} if the list contained the specified element * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { for (Node x = last; x != null; x = x.prev) { @@ -913,7 +943,7 @@ public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Linke * @throws IndexOutOfBoundsException {@inheritDoc} * @see List#listIterator(int) */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedList this, @NonNegative int index) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty LinkedList this, @NonNegative int index) { checkPositionIndex(index); return new ListItr(index); } @@ -948,10 +978,12 @@ public E next(@NonEmpty ListItr this) { return lastReturned.item; } + @Pure public boolean hasPrevious() { return nextIndex > 0; } + @DoesNotUnrefineReceiver("modifiability") public E previous() { checkForComodification(); if (!hasPrevious()) @@ -962,14 +994,17 @@ public E previous() { return lastReturned.item; } + @Pure public int nextIndex() { return nextIndex; } + @Pure public int previousIndex() { return nextIndex - 1; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { checkForComodification(); if (lastReturned == null) @@ -985,6 +1020,7 @@ public void remove() { expectedModCount++; } + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); @@ -992,6 +1028,7 @@ public void set(E e) { lastReturned.item = e; } + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { checkForComodification(); lastReturned = null; @@ -1035,7 +1072,7 @@ private static class Node { /** * @since 1.6 */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty LinkedList this) { return new DescendingIterator(); } @@ -1053,6 +1090,7 @@ public boolean hasNext() { public E next(@NonEmpty DescendingIterator this) { return itr.previous(); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { itr.remove(); } @@ -1150,7 +1188,6 @@ private LinkedList superClone() { * this list * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length < size) @@ -1353,18 +1390,22 @@ public String toString() { return rlist.toString(); } + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return rlist.retainAll(c); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return rlist.removeAll(c); } + @Pure public boolean containsAll(Collection c) { return rlist.containsAll(c); } + @Pure public boolean isEmpty() { return rlist.isEmpty(); } @@ -1377,10 +1418,12 @@ public Stream stream() { return rlist.stream(); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return rlist.removeIf(filter); } + @SideEffectFree public T[] toArray(IntFunction generator) { return rlist.toArray(generator); } @@ -1409,10 +1452,12 @@ public ListIterator listIterator() { return rlist.listIterator(); } + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { rlist.sort(c); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { rlist.replaceAll(operator); } @@ -1429,6 +1474,7 @@ public T[] toArray(T[] a) { return rlist.toArray(a); } + @SideEffectFree public Object[] toArray() { return rlist.toArray(); } @@ -1441,26 +1487,32 @@ public ListIterator listIterator(int index) { return rlist.listIterator(index); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(Object o) { return rdeque.removeLastOccurrence(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(Object o) { return rdeque.removeFirstOccurrence(o); } + @DoesNotUnrefineReceiver("modifiability") public E pop() { return rdeque.pop(); } + @DoesNotUnrefineReceiver("modifiability") public void push(E e) { rdeque.push(e); } + @DoesNotUnrefineReceiver("modifiability") public E pollLast() { return rdeque.pollLast(); } + @DoesNotUnrefineReceiver("modifiability") public E pollFirst() { return rdeque.pollFirst(); } @@ -1473,22 +1525,27 @@ public E peekFirst() { return rdeque.peekFirst(); } + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e) { return rdeque.offerLast(e); } + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e) { return rdeque.offerFirst(e); } + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { return rdeque.offer(e); } + @DoesNotUnrefineReceiver("modifiability") public E remove() { return rdeque.remove(); } + @DoesNotUnrefineReceiver("modifiability") public E poll() { return rdeque.poll(); } @@ -1501,78 +1558,99 @@ public E peek() { return rdeque.peek(); } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { return rlist.lastIndexOf(o); } + @Pure + @StaticallyExecutable public int indexOf(Object o) { return rlist.indexOf(o); } + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { return rlist.remove(index); } + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { rlist.add(index, element); } + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { return rlist.set(index, element); } + @Pure public E get(int index) { return rlist.get(index); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { rlist.clear(); } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { return rlist.addAll(index, c); } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { return rlist.addAll(c); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object o) { return rlist.remove(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return rlist.add(e); } + @Pure public int size() { return rlist.size(); } + @Pure public boolean contains(Object o) { return rlist.contains(o); } + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { rdeque.addLast(e); } + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { rdeque.addFirst(e); } + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { return rdeque.removeLast(); } + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { return rdeque.removeFirst(); } + @Pure public E getLast() { return rdeque.getLast(); } + @Pure public E getFirst() { return rdeque.getFirst(); } diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 7ffed30a226c..7c7e1df2c2af 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -33,13 +33,13 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -48,6 +48,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -216,7 +217,7 @@ public interface List extends SequencedCollection { * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List this); + @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); /** * Returns an array containing all of the elements in this list in proper @@ -276,7 +277,6 @@ public interface List extends SequencedCollection { * this list * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T[] toArray(@UnknownModifiability List this, @PolyNull T[] a); @@ -643,6 +643,8 @@ default void sort(@Replaceable List this, Comparator c) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E set(@Replaceable @GuardSatisfied List this, @IndexFor({"this"}) int index, E element); /** @@ -737,7 +739,7 @@ default void sort(@Replaceable List this, Comparator c) { * @return a list iterator over the elements in this list (in proper * sequence) */ - @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List this); + @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); /** * Returns a list iterator over the elements in this list (in proper @@ -754,7 +756,7 @@ default void sort(@Replaceable List this, Comparator c) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index > size()}) */ - @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); + @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); // View @@ -793,7 +795,7 @@ default void sort(@Replaceable List this, Comparator c) { * fromIndex > toIndex}) */ @SideEffectFree - @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink List this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex); + @PolyGrowShrink @PolyModifiable List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink List this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex); /** * Creates a {@link Spliterator} over the elements in this list. @@ -878,6 +880,7 @@ default void addLast(@Growable List this, E e) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getFirst() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -896,6 +899,7 @@ default E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getLast() { if (this.isEmpty()) { throw new NoSuchElementException(); diff --git a/src/java.base/share/classes/java/util/ListIterator.java b/src/java.base/share/classes/java/util/ListIterator.java index 098b51abaa26..b92d41fd16f1 100644 --- a/src/java.base/share/classes/java/util/ListIterator.java +++ b/src/java.base/share/classes/java/util/ListIterator.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -100,6 +101,7 @@ public interface ListIterator extends Iterator { * @throws NoSuchElementException if the iteration has no next element */ @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E next(@GuardSatisfied @NonEmpty ListIterator this); /** @@ -126,6 +128,7 @@ public interface ListIterator extends Iterator { * @throws NoSuchElementException if the iteration has no previous * element */ + @DoesNotUnrefineReceiver("modifiability") E previous(@GuardSatisfied ListIterator this); /** @@ -169,6 +172,7 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ + @DoesNotUnrefineReceiver("modifiability") void remove(@Shrinkable @GuardSatisfied ListIterator this); /** @@ -191,6 +195,7 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ + @DoesNotUnrefineReceiver("modifiability") void set(@Replaceable @GuardSatisfied ListIterator this, E e); /** @@ -213,5 +218,6 @@ public interface ListIterator extends Iterator { * @throws IllegalArgumentException if some aspect of this element * prevents it from being added to this list */ + @DoesNotUnrefineReceiver("modifiability") void add(@Growable @GuardSatisfied ListIterator this, E e); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 1600c0c611e1..a21052e75bb3 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -28,14 +28,14 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; -import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -48,6 +48,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.aliasing.qual.NonLeaked; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -310,6 +311,7 @@ public interface Map { @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable V put(@Growable @Replaceable @GuardSatisfied Map this, K key, V value); /** @@ -341,6 +343,7 @@ public interface Map { * map does not permit null keys ({@linkplain Collection##optional-restrictions optional}) */ @CFComment("nullness: key is not @Nullable because this map might not permit null values") + @DoesNotUnrefineReceiver("modifiability") @Nullable V remove(@Shrinkable @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); @@ -367,6 +370,7 @@ public interface Map { * @throws IllegalArgumentException if some property of a key or value in * the specified map prevents it from being stored in this map */ + @DoesNotUnrefineReceiver("modifiability") void putAll(@Growable @Replaceable @GuardSatisfied Map this, Map m); /** @@ -376,6 +380,7 @@ public interface Map { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this map */ + @DoesNotUnrefineReceiver("modifiability") void clear(@Shrinkable @GuardSatisfied Map this); @@ -397,7 +402,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @PolyShrink @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @PolyNonEmpty @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -415,7 +420,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @PolyShrink @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @PolyNonEmpty @PolyShrink Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -434,7 +439,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @PolyShrink @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @PolyNonEmpty @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the @@ -540,6 +545,7 @@ interface Entry { * required to, throw this exception if the entry has been * removed from the backing map. */ + @DoesNotUnrefineReceiver("modifiability") V setValue(Map.@Replaceable @GuardSatisfied Entry this, V value); /** @@ -705,6 +711,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @Nullable Object o); /** @@ -720,6 +727,7 @@ public static Comparator> comparingByValue(Comparator this); // Defaultable methods @@ -777,6 +785,7 @@ default V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultV * removed during iteration * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void forEach(@NonLeaked BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { @@ -827,6 +836,7 @@ default void forEach(@NonLeaked BiConsumer action) { * removed during iteration * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void replaceAll(@Replaceable Map this, BiFunction function) { Objects.requireNonNull(function); for (Map.Entry entry : entrySet()) { @@ -894,6 +904,7 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V value) { V v = get(key); if (v == null) { @@ -938,6 +949,7 @@ default void replaceAll(@Replaceable Map this, BiFunction this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || @@ -988,6 +1000,7 @@ default boolean remove(@Shrinkable Map this, @GuardSatisfied @UnknownSigne * or value prevents it from being stored in this map * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default boolean replace(@Replaceable Map this, K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || @@ -1036,6 +1049,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * or value prevents it from being stored in this map * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V replace(@Replaceable Map this, K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { @@ -1118,6 +1132,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyNull V computeIfAbsent(@Growable Map this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -1195,6 +1210,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V computeIfPresent(@Shrinkable @Replaceable Map this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1281,6 +1297,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V compute(@Modifiable Map this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1379,6 +1396,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V merge(@Modifiable Map this, K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index e110fe69db53..f7462ab489fa 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,11 +36,12 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -126,6 +127,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree Map.@Nullable Entry lowerEntry(K key); /** @@ -140,6 +142,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree @Nullable K lowerKey(K key); /** @@ -155,6 +158,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree Map.@Nullable Entry floorEntry(K key); /** @@ -169,6 +173,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree @Nullable K floorKey(K key); /** @@ -184,6 +189,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree Map.@Nullable Entry ceilingEntry(K key); /** @@ -198,6 +204,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree @Nullable K ceilingKey(K key); /** @@ -213,6 +220,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree Map.@Nullable Entry higherEntry(K key); /** @@ -227,6 +235,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ + @SideEffectFree @Nullable K higherKey(K key); /** @@ -236,6 +245,7 @@ public interface NavigableMap extends SortedMap { * @return an entry with the least key, * or {@code null} if this map is empty */ + @SideEffectFree Map.@Nullable Entry firstEntry(); /** @@ -245,6 +255,7 @@ public interface NavigableMap extends SortedMap { * @return an entry with the greatest key, * or {@code null} if this map is empty */ + @SideEffectFree Map.@Nullable Entry lastEntry(); /** @@ -254,6 +265,7 @@ public interface NavigableMap extends SortedMap { * @return the removed first entry of this map, * or {@code null} if this map is empty */ + @DoesNotUnrefineReceiver("modifiability") Map.@Nullable Entry pollFirstEntry(@Shrinkable @GuardSatisfied NavigableMap this); /** @@ -263,6 +275,7 @@ public interface NavigableMap extends SortedMap { * @return the removed last entry of this map, * or {@code null} if this map is empty */ + @DoesNotUnrefineReceiver("modifiability") Map.@Nullable Entry pollLastEntry(@Shrinkable @GuardSatisfied NavigableMap this); /** diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 300a891ff253..8c600a90b269 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -37,10 +37,11 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -112,6 +113,7 @@ public interface NavigableSet extends SortedSet { * @throws NullPointerException if the specified element is null * and this set does not permit null elements */ + @Pure @Nullable E lower(E e); /** @@ -126,6 +128,7 @@ public interface NavigableSet extends SortedSet { * @throws NullPointerException if the specified element is null * and this set does not permit null elements */ + @Pure @Nullable E floor(E e); /** @@ -140,6 +143,7 @@ public interface NavigableSet extends SortedSet { * @throws NullPointerException if the specified element is null * and this set does not permit null elements */ + @Pure @Nullable E ceiling(E e); /** @@ -154,6 +158,7 @@ public interface NavigableSet extends SortedSet { * @throws NullPointerException if the specified element is null * and this set does not permit null elements */ + @Pure @Nullable E higher(E e); /** @@ -162,6 +167,7 @@ public interface NavigableSet extends SortedSet { * * @return the first element, or {@code null} if this set is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollFirst(@GuardSatisfied NavigableSet this); /** @@ -170,6 +176,7 @@ public interface NavigableSet extends SortedSet { * * @return the last element, or {@code null} if this set is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollLast(@GuardSatisfied NavigableSet this); /** @@ -178,7 +185,7 @@ public interface NavigableSet extends SortedSet { * @return an iterator over the elements in this set, in ascending order */ @SideEffectFree - @PolyModifiable@PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet this); + @PolyModifiable@PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet this); /** * Returns a reverse order view of the elements contained in this set. @@ -195,6 +202,7 @@ public interface NavigableSet extends SortedSet { * * @return a reverse order view of this set */ + @DoesNotUnrefineReceiver("modifiability") @PolyModifiable NavigableSet descendingSet(@PolyModifiable NavigableSet this); /** @@ -203,6 +211,7 @@ public interface NavigableSet extends SortedSet { * * @return an iterator over the elements in this set, in descending order */ + @DoesNotUnrefineReceiver("modifiability") @PolyModifiable Iterator descendingIterator(@PolyModifiable NavigableSet this); /** @@ -351,6 +360,7 @@ public interface NavigableSet extends SortedSet { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default E removeFirst(@Shrinkable NavigableSet this) { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -370,6 +380,7 @@ default E removeFirst(@Shrinkable NavigableSet this) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default E removeLast(@Shrinkable NavigableSet this) { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -390,6 +401,7 @@ default E removeLast(@Shrinkable NavigableSet this) { * @return a reverse-ordered view of this collection, as a {@code NavigableSet} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyModifiable NavigableSet reversed(@PolyModifiable NavigableSet this) { return this.descendingSet(); } diff --git a/src/java.base/share/classes/java/util/PrimitiveIterator.java b/src/java.base/share/classes/java/util/PrimitiveIterator.java index ed9efa28db27..150564d3774a 100644 --- a/src/java.base/share/classes/java/util/PrimitiveIterator.java +++ b/src/java.base/share/classes/java/util/PrimitiveIterator.java @@ -26,6 +26,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.nonempty.qual.NonEmpty; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.framework.qual.AnnotatedFor; import java.util.function.Consumer; @@ -90,6 +91,7 @@ public interface PrimitiveIterator extends Iterator { * @throws NullPointerException if the specified action is null */ @SuppressWarnings("overloads") + @DoesNotUnrefineReceiver("modifiability") void forEachRemaining(T_CONS action); /** @@ -105,6 +107,7 @@ public static interface OfInt extends PrimitiveIterator { * @return the next {@code int} element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ + @DoesNotUnrefineReceiver("modifiability") int nextInt(@NonEmpty OfInt this); /** @@ -116,6 +119,7 @@ public static interface OfInt extends PrimitiveIterator { * action.accept(nextInt()); * } */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(IntConsumer action) { Objects.requireNonNull(action); while (hasNext()) @@ -129,6 +133,7 @@ default void forEachRemaining(IntConsumer action) { * {@link #nextInt()}, and returns that boxed result. */ @Override + @DoesNotUnrefineReceiver("modifiability") default Integer next(PrimitiveIterator.@GuardSatisfied OfInt this) { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()"); @@ -145,6 +150,7 @@ default Integer next(PrimitiveIterator.@GuardSatisfied OfInt this) { * and then passed to {@link #forEachRemaining}. */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { if (action instanceof IntConsumer) { forEachRemaining((IntConsumer) action); @@ -173,6 +179,7 @@ public static interface OfLong extends PrimitiveIterator { * @return the next {@code long} element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ + @DoesNotUnrefineReceiver("modifiability") long nextLong(@NonEmpty OfLong this); /** @@ -184,6 +191,7 @@ public static interface OfLong extends PrimitiveIterator { * action.accept(nextLong()); * } */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(LongConsumer action) { Objects.requireNonNull(action); while (hasNext()) @@ -197,6 +205,7 @@ default void forEachRemaining(LongConsumer action) { * {@link #nextLong()}, and returns that boxed result. */ @Override + @DoesNotUnrefineReceiver("modifiability") default Long next(PrimitiveIterator.@GuardSatisfied OfLong this) { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.nextLong()"); @@ -213,6 +222,7 @@ default Long next(PrimitiveIterator.@GuardSatisfied OfLong this) { * and then passed to {@link #forEachRemaining}. */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { if (action instanceof LongConsumer) { forEachRemaining((LongConsumer) action); @@ -240,6 +250,7 @@ public static interface OfDouble extends PrimitiveIterator */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(DoubleConsumer action) { Objects.requireNonNull(action); while (hasNext()) @@ -264,6 +276,7 @@ default void forEachRemaining(DoubleConsumer action) { * {@link #nextDouble()}, and returns that boxed result. */ @Override + @DoesNotUnrefineReceiver("modifiability") default Double next(PrimitiveIterator.@GuardSatisfied OfDouble this) { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.nextLong()"); @@ -281,6 +294,7 @@ default Double next(PrimitiveIterator.@GuardSatisfied OfDouble this) { * {@link #forEachRemaining}. */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { if (action instanceof DoubleConsumer) { forEachRemaining((DoubleConsumer) action); diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index b9dcca378005..02625197edd7 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -478,7 +478,6 @@ public boolean contains(@GuardSatisfied PriorityQueue this, @GuardSatisfied @ * this queue * @throws NullPointerException if the specified array is null */ - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { final int size = this.size; if (a.length < size) @@ -497,7 +496,7 @@ public boolean contains(@GuardSatisfied PriorityQueue this, @GuardSatisfied @ * @return an iterator over the elements in this queue */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty PriorityQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty PriorityQueue this) { return new Itr(); } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index a25c6f4be6f8..4ac828027799 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.propkey.qual.PropertyKey; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -238,6 +239,7 @@ private Properties(Properties defaults, int initialCapacity) { * @see #getProperty * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable Object setProperty(@GuardSatisfied Properties this, @PropertyKey String key, String value) { return put(key, value); } @@ -1363,21 +1365,25 @@ public boolean containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object k } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized Object put(Object key, Object value) { return map.put(key, value); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized Object remove(@GuardSatisfied @Nullable @UnknownSignedness Object key) { return map.remove(key); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void putAll(Map t) { map.putAll(t); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void clear() { map.clear(); } @@ -1424,7 +1430,9 @@ private EntrySet(Set> entrySet) { @Override public boolean contains(@UnknownSignedness Object o) { return entrySet.contains(o); } @Override public Object[] toArray() { return entrySet.toArray(); } @Override public @Nullable T[] toArray(@PolyNull T[] a) { return entrySet.toArray(a); } + @DoesNotUnrefineReceiver("modifiability") @Override public void clear() { entrySet.clear(); } + @DoesNotUnrefineReceiver("modifiability") @Override public boolean remove(@UnknownSignedness Object o) { return entrySet.remove(o); } @Override @@ -1459,11 +1467,13 @@ public String toString() { } @Override + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return entrySet.removeAll(c); } @Override + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return entrySet.retainAll(c); } @@ -1474,11 +1484,13 @@ public Iterator> iterator() { } } + @Pure @Override public synchronized boolean equals(Object o) { return map.equals(o); } + @Pure @Override public synchronized int hashCode() { return map.hashCode(); @@ -1491,54 +1503,64 @@ public Object getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object k } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void forEach(BiConsumer action) { map.forEach(action); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(BiFunction function) { map.replaceAll(function); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized Object putIfAbsent(Object key, Object value) { return map.putIfAbsent(key, value); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return map.remove(key, value); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean replace(Object key, Object oldValue, Object newValue) { return map.replace(key, oldValue, newValue); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized Object replace(Object key, Object value) { return map.replace(key, value); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull Object computeIfAbsent(Object key, Function mappingFunction) { return map.computeIfAbsent(key, mappingFunction); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull Object computeIfPresent(Object key, BiFunction remappingFunction) { return map.computeIfPresent(key, remappingFunction); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull Object compute(Object key, BiFunction remappingFunction) { return map.compute(key, remappingFunction); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable Object merge(Object key, Object value, BiFunction remappingFunction) { return map.merge(key, value, remappingFunction); diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index 284ae958a655..1d4f0b21191e 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -38,12 +38,13 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -169,6 +170,7 @@ public interface Queue extends Collection { * prevents it from being added to this queue */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(@Growable @GuardSatisfied Queue this, E e); /** @@ -188,6 +190,7 @@ public interface Queue extends Collection { * @throws IllegalArgumentException if some property of this element * prevents it from being added to this queue */ + @DoesNotUnrefineReceiver("modifiability") boolean offer(@Growable Queue this, E e); /** @@ -198,6 +201,7 @@ public interface Queue extends Collection { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + @DoesNotUnrefineReceiver("modifiability") E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Queue this); /** @@ -206,6 +210,7 @@ public interface Queue extends Collection { * * @return the head of this queue, or {@code null} if this queue is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink Queue this); /** @@ -216,6 +221,7 @@ public interface Queue extends Collection { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + @Pure E element(@GuardSatisfied @NonEmpty Queue this); /** @@ -224,5 +230,6 @@ public interface Queue extends Collection { * * @return the head of this queue, or {@code null} if this queue is empty */ + @DoesNotUnrefineReceiver("modifiability") @Nullable E peek(); } diff --git a/src/java.base/share/classes/java/util/RegularEnumSet.java b/src/java.base/share/classes/java/util/RegularEnumSet.java index a898d1090df2..9b5a5e2dddaf 100644 --- a/src/java.base/share/classes/java/util/RegularEnumSet.java +++ b/src/java.base/share/classes/java/util/RegularEnumSet.java @@ -36,6 +36,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -63,15 +64,18 @@ final class RegularEnumSet> extends EnumSet { super(elementType, universe); } + @DoesNotUnrefineReceiver("modifiability") void addRange(E from, E to) { elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal(); } + @DoesNotUnrefineReceiver("modifiability") void addAll() { if (universe.length != 0) elements = -1L >>> -universe.length; } + @DoesNotUnrefineReceiver("modifiability") void complement() { if (universe.length != 0) { elements = ~elements; @@ -89,6 +93,7 @@ void complement() { * * @return an iterator over the elements contained in this set */ + @DoesNotUnrefineReceiver("modifiability") public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty RegularEnumSet this) { return new EnumSetIterator<>(); } @@ -126,6 +131,7 @@ public E next(@NonEmpty EnumSetIterator this) { return (E) universe[Long.numberOfTrailingZeros(lastReturned)]; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == 0) throw new IllegalStateException(); @@ -184,6 +190,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object e) { * @throws NullPointerException if {@code e} is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { typeCheck(e); @@ -198,6 +205,7 @@ public boolean add(E e) { * @param e element to be removed from this set, if present * @return {@code true} if the set contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object e) { if (e == null) return false; @@ -240,6 +248,7 @@ public boolean containsAll(Collection c) { * @throws NullPointerException if the specified collection or any * of its elements are null */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { if (!(c instanceof RegularEnumSet es)) return super.addAll(c); @@ -265,6 +274,7 @@ public boolean addAll(Collection c) { * @return {@code true} if this set changed as a result of the call * @throws NullPointerException if the specified collection is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { if (!(c instanceof RegularEnumSet es)) return super.removeAll(c); @@ -285,6 +295,7 @@ public boolean removeAll(Collection c) { * @return {@code true} if this set changed as a result of the call * @throws NullPointerException if the specified collection is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { if (!(c instanceof RegularEnumSet es)) return super.retainAll(c); @@ -303,6 +314,7 @@ public boolean retainAll(Collection c) { /** * Removes all of the elements from this set. */ + @DoesNotUnrefineReceiver("modifiability") public void clear() { elements = 0; } diff --git a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java index a580ad8f7db3..38e62869d42a 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java @@ -157,6 +157,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -166,6 +167,7 @@ public T[] toArray(T[] a) { return ArraysSupport.toArrayReversed(base, a); } + @SideEffectFree public T[] toArray(IntFunction generator) { return ArraysSupport.reverse(base.toArray(generator)); } @@ -201,14 +203,17 @@ public Iterator descendingIterator() { return base.iterator(); } + @Pure public E element() { return base.getLast(); } + @Pure public E getFirst() { return base.getLast(); } + @Pure public E getLast() { return base.getFirst(); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderListView.java b/src/java.base/share/classes/java/util/ReverseOrderListView.java index 0f7409bef16d..4826354fb5ea 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderListView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderListView.java @@ -106,6 +106,7 @@ public E next() { return it.previous(); } + @Pure public boolean hasPrevious() { return it.hasNext(); } @@ -283,6 +284,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -292,6 +294,7 @@ public T[] toArray(T[] a) { return ArraysSupport.toArrayReversed(base, a); } + @SideEffectFree public T[] toArray(IntFunction generator) { return ArraysSupport.reverse(base.toArray(generator)); } @@ -336,17 +339,22 @@ public boolean addAll(int index, Collection c) { } } + @Pure public E get(int i) { int size = base.size(); Objects.checkIndex(i, size); return base.get(size - i - 1); } + @Pure + @StaticallyExecutable public int indexOf(Object o) { int i = base.lastIndexOf(o); return i == -1 ? -1 : base.size() - i - 1; } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { int i = base.indexOf(o); return i == -1 ? -1 : base.size() - i - 1; diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 404950e8fd54..60c1486e15f5 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -168,6 +168,7 @@ public V putLast(K k, V v) { // ========== SortedMap ========== + @Pure public Comparator comparator() { return cmp; } @@ -428,6 +429,7 @@ public int size() { return entrySet().size(); } + @Pure public Comparator comparator() { return cmp; } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java index 678c82fc311e..36774ea6454e 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java @@ -166,6 +166,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -175,18 +176,22 @@ public T[] toArray(T[] a) { return ArraysSupport.toArrayReversed(base, a); } + @SideEffectFree public T[] toArray(IntFunction generator) { return ArraysSupport.reverse(base.toArray(generator)); } // ========== SortedSet ========== + @Pure public Comparator comparator() { return comp; } + @Pure public E first() { return base.last(); } + @Pure public E last() { return base.first(); } public SortedSet headSet(E to) { @@ -327,6 +332,7 @@ public int size() { return sz; } + @Pure public Comparator comparator() { return ReverseOrderSortedSetView.this.comparator(); } diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index af1567e64e52..eb0960b4c4eb 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; /** @@ -92,6 +93,7 @@ public interface SequencedCollection extends Collection { * * @return a reverse-ordered view of this collection */ + @DoesNotUnrefineReceiver("modifiability") SequencedCollection reversed(); /** @@ -108,6 +110,7 @@ public interface SequencedCollection extends Collection { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + @DoesNotUnrefineReceiver("modifiability") default void addFirst(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -126,6 +129,7 @@ default void addFirst(@Growable SequencedCollection this, E e) { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + @DoesNotUnrefineReceiver("modifiability") default void addLast(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -142,6 +146,7 @@ default void addLast(@Growable SequencedCollection this, E e) { * @return the retrieved element * @throws NoSuchElementException if this collection is empty */ + @Pure default E getFirst() { return this.iterator().next(); } @@ -158,6 +163,7 @@ default E getFirst() { * @return the retrieved element * @throws NoSuchElementException if this collection is empty */ + @Pure default E getLast() { return this.reversed().iterator().next(); } @@ -177,6 +183,7 @@ default E getLast() { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + @DoesNotUnrefineReceiver("modifiability") default E removeFirst(@Shrinkable SequencedCollection this) { var it = this.iterator(); E e = it.next(); @@ -199,6 +206,7 @@ default E removeFirst(@Shrinkable SequencedCollection this) { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + @DoesNotUnrefineReceiver("modifiability") default E removeLast(@Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); E e = it.next(); diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 8a1f25ebc733..492615adabc0 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -28,10 +28,11 @@ import jdk.internal.util.NullableKeyValueHolder; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; /** * A Map that has a well-defined encounter order, that supports operations at both ends, and @@ -140,6 +141,7 @@ public interface SequencedMap extends Map { * * @return a reverse-ordered view of this map */ + @DoesNotUnrefineReceiver("modifiability") SequencedMap reversed(); /** @@ -154,6 +156,7 @@ public interface SequencedMap extends Map { * @return the first key-value mapping, * or {@code null} if this map is empty */ + @SideEffectFree default Map.Entry firstEntry() { var it = entrySet().iterator(); return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null; @@ -171,6 +174,7 @@ default Map.Entry firstEntry() { * @return the last key-value mapping, * or {@code null} if this map is empty */ + @SideEffectFree default Map.Entry lastEntry() { var it = reversed().entrySet().iterator(); return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null; @@ -190,6 +194,7 @@ default Map.Entry lastEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + @DoesNotUnrefineReceiver("modifiability") default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { var it = entrySet().iterator(); if (it.hasNext()) { @@ -215,6 +220,7 @@ default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + @DoesNotUnrefineReceiver("modifiability") default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { var it = reversed().entrySet().iterator(); if (it.hasNext()) { @@ -241,6 +247,7 @@ default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + @DoesNotUnrefineReceiver("modifiability") default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -260,6 +267,7 @@ default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + @DoesNotUnrefineReceiver("modifiability") default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -278,6 +286,7 @@ default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { * * @return a {@code SequencedSet} view of this map's {@code keySet} */ + @DoesNotUnrefineReceiver("modifiability") default @PolyShrink SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { Collection view() { @@ -311,6 +320,7 @@ public int hashCode() { * * @return a {@code SequencedCollection} view of this map's {@code values} collection */ + @DoesNotUnrefineReceiver("modifiability") default @PolyShrink SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { Collection view() { @@ -337,6 +347,7 @@ public SequencedCollection reversed() { * * @return a {@code SequencedSet} view of this map's {@code entrySet} */ + @DoesNotUnrefineReceiver("modifiability") default @PolyShrink SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { class SeqEntrySet extends AbstractMap.ViewCollection> implements SequencedSet> { diff --git a/src/java.base/share/classes/java/util/SequencedSet.java b/src/java.base/share/classes/java/util/SequencedSet.java index c02bfc123ff8..d4bac4cd6747 100644 --- a/src/java.base/share/classes/java/util/SequencedSet.java +++ b/src/java.base/share/classes/java/util/SequencedSet.java @@ -25,6 +25,8 @@ package java.util; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; + /** * A collection that is both a {@link SequencedCollection} and a {@link Set}. As such, * it can be thought of either as a {@code Set} that also has a well-defined @@ -54,5 +56,6 @@ public interface SequencedSet extends SequencedCollection, Set { * * @return a reverse-ordered view of this collection, as a {@code SequencedSet} */ + @DoesNotUnrefineReceiver("modifiability") SequencedSet reversed(); } diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 888f6f5e64b2..b8d6a3878110 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -28,11 +28,11 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -41,6 +41,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -247,7 +248,6 @@ public interface Set extends Collection { * set * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T [] toArray(@UnknownModifiability Set this, @PolyNull T[] a); @@ -284,6 +284,7 @@ public interface Set extends Collection { * prevents it from being added to this set */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(@Growable @GuardSatisfied Set this, E e); @@ -308,6 +309,7 @@ public interface Set extends Collection { * @throws UnsupportedOperationException if the {@code remove} operation * is not supported by this set */ + @DoesNotUnrefineReceiver("modifiability") boolean remove(@Shrinkable @GuardSatisfied Set this, @UnknownSignedness Object o); @@ -358,6 +360,7 @@ public interface Set extends Collection { * @see #add(Object) */ @EnsuresNonEmptyIf(result = true, expression = "this") + @DoesNotUnrefineReceiver("modifiability") boolean addAll(@Growable @GuardSatisfied Set this, Collection c); /** @@ -381,6 +384,7 @@ public interface Set extends Collection { * or if the specified collection is null * @see #remove(Object) */ + @DoesNotUnrefineReceiver("modifiability") boolean retainAll(@Shrinkable @GuardSatisfied Set this, Collection c); /** @@ -404,6 +408,7 @@ public interface Set extends Collection { * @see #remove(Object) * @see #contains(Object) */ + @DoesNotUnrefineReceiver("modifiability") boolean removeAll(@Shrinkable @GuardSatisfied Set this, Collection c); /** @@ -413,6 +418,7 @@ public interface Set extends Collection { * @throws UnsupportedOperationException if the {@code clear} method * is not supported by this set */ + @DoesNotUnrefineReceiver("modifiability") void clear(@Shrinkable @GuardSatisfied Set this); @@ -473,6 +479,7 @@ public interface Set extends Collection { * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default Spliterator spliterator(@UnknownModifiability Set this) { return Spliterators.spliterator(this, Spliterator.DISTINCT); } diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 4958e5a52acf..538636aef665 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -318,6 +319,7 @@ public interface SortedMap extends SequencedMap { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") default V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -334,6 +336,7 @@ default V putFirst(K k, V v) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") default V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -348,6 +351,7 @@ default V putLast(K k, V v) { * @return a reverse-ordered view of this map, as a {@code SortedMap} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyModifiable SortedMap reversed(@PolyModifiable SortedMap this) { return ReverseOrderSortedMapView.of(this); } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index f185cbb43c26..0c82154527c3 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -226,7 +227,7 @@ public interface SortedSet extends Set, SequencedSet { * @return the first (lowest) element currently in this set * @throws NoSuchElementException if this set is empty */ - @SideEffectFree + @Pure E first(@GuardSatisfied @NonEmpty SortedSet this); /** @@ -235,7 +236,7 @@ public interface SortedSet extends Set, SequencedSet { * @return the last (highest) element currently in this set * @throws NoSuchElementException if this set is empty */ - @SideEffectFree + @Pure E last(@GuardSatisfied @NonEmpty SortedSet this); /** @@ -270,6 +271,7 @@ public interface SortedSet extends Set, SequencedSet { * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default Spliterator spliterator() { return new Spliterators.IteratorSpliterator( this, Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED) { @@ -294,6 +296,7 @@ public Comparator getComparator() { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") default void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -310,6 +313,7 @@ default void addFirst(E e) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") default void addLast(E e) { throw new UnsupportedOperationException(); } @@ -323,6 +327,7 @@ default void addLast(E e) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getFirst() { return this.first(); } @@ -336,6 +341,7 @@ default E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getLast() { return this.last(); } @@ -352,6 +358,7 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default E removeFirst(@Shrinkable SortedSet this) { E e = this.first(); this.remove(e); @@ -370,6 +377,7 @@ default E removeFirst(@Shrinkable SortedSet this) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default E removeLast(@Shrinkable SortedSet this) { E e = this.last(); this.remove(e); @@ -386,6 +394,7 @@ default E removeLast(@Shrinkable SortedSet this) { * @return a reverse-ordered view of this collection, as a {@code SortedSet} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyModifiable SortedSet reversed(@PolyModifiable SortedSet this) { return ReverseOrderSortedSetView.of(this); } diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 4a960c5b90db..53d7877ec5ac 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -33,6 +33,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; /** * The {@code Stack} class represents a last-in-first-out @@ -75,6 +76,7 @@ public Stack() { * @return the {@code item} argument. * @see java.util.Vector#addElement */ + @DoesNotUnrefineReceiver("modifiability") public E push(@GuardSatisfied Stack this, E item) { addElement(item); @@ -89,6 +91,7 @@ public E push(@GuardSatisfied Stack this, E item) { * of the {@code Vector} object). * @throws EmptyStackException if this stack is empty. */ + @DoesNotUnrefineReceiver("modifiability") public synchronized E pop(@GuardSatisfied @NonEmpty @CanShrink Stack this) { E obj; int len = size(); @@ -142,6 +145,7 @@ public boolean empty() { * the object is located; the return value {@code -1} * indicates that the object is not on the stack. */ + @Pure public synchronized int search(Object o) { int i = lastIndexOf(o); diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index bea1bdc2742a..a9f5474fece6 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -29,11 +29,11 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -43,6 +43,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -316,6 +317,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied * and this map uses natural ordering, or its comparator * does not permit null keys */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable V get(@GuardSatisfied TreeMap this, @UnknownSignedness @GuardSatisfied Object key) { Entry p = getEntry(key); return (p==null ? null : p.value); @@ -329,6 +331,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied /** * @throws NoSuchElementException {@inheritDoc} */ + @SideEffectFree public @KeyFor("this") K firstKey(@NonEmpty TreeMap this) { return key(getFirstEntry()); } @@ -336,6 +339,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied /** * @throws NoSuchElementException {@inheritDoc} */ + @SideEffectFree public @KeyFor("this") K lastKey(@NonEmpty TreeMap this) { return key(getLastEntry()); } @@ -349,6 +353,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -362,6 +367,7 @@ public V putFirst(K k, V v) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -378,6 +384,7 @@ public V putLast(K k, V v) { * the specified map contains a null key and this map does not * permit null keys */ + @DoesNotUnrefineReceiver("modifiability") public void putAll(@Growable @Replaceable @GuardSatisfied TreeMap this, Map map) { int mapSize = map.size(); if (size==0 && mapSize!=0 && map instanceof SortedMap) { @@ -599,11 +606,13 @@ final Entry getLowerEntry(K key) { * does not permit null keys */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@Growable @Replaceable @GuardSatisfied TreeMap this, K key, V value) { return put(key, value, true); } @Override + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(@Growable TreeMap this, K key, V value) { return put(key, value, false); } @@ -619,6 +628,7 @@ public V putIfAbsent(@Growable TreeMap this, K key, V value) { * mapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V computeIfAbsent(@Growable TreeMap this, K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V newValue; @@ -689,6 +699,7 @@ else if (cmp > 0) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V computeIfPresent(@Shrinkable @Replaceable TreeMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Entry oldEntry = getEntry(key); @@ -710,6 +721,7 @@ public V computeIfPresent(@Shrinkable @Replaceable TreeMap this, K key, BiF * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V compute(@Modifiable TreeMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V newValue; @@ -772,6 +784,7 @@ else if (cmp > 0) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V merge(@Modifiable TreeMap this, K key, V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); @@ -946,6 +959,7 @@ private V mergeValue(Entry t, V value, BiFunction this, @GuardSatisfied @UnknownSignedness Object key) { Entry p = getEntry(key); if (p == null) @@ -960,6 +974,7 @@ private V mergeValue(Entry t, V value, BiFunction this) { modCount++; size = 0; @@ -972,6 +987,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * * @return a shallow copy of this map */ + @DoesNotUnrefineReceiver("modifiability") public @Modifiable Object clone(@GuardSatisfied TreeMap this) { TreeMap clone; try { @@ -1002,6 +1018,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { /** * @since 1.6 */ + @SideEffectFree public Map.@Nullable Entry firstEntry() { return exportEntry(getFirstEntry()); } @@ -1009,6 +1026,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { /** * @since 1.6 */ + @SideEffectFree public Map.@Nullable Entry lastEntry() { return exportEntry(getLastEntry()); } @@ -1016,6 +1034,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { /** * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public Map.@Nullable Entry pollFirstEntry(@Shrinkable @GuardSatisfied TreeMap this) { Entry p = getFirstEntry(); Map.Entry result = exportEntry(p); @@ -1027,6 +1046,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { /** * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public Map.@Nullable Entry pollLastEntry(@Shrinkable @GuardSatisfied TreeMap this) { Entry p = getLastEntry(); Map.Entry result = exportEntry(p); @@ -1042,6 +1062,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public Map.@Nullable Entry lowerEntry(K key) { return exportEntry(getLowerEntry(key)); } @@ -1053,6 +1074,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public @Nullable K lowerKey(K key) { return keyOrNull(getLowerEntry(key)); } @@ -1064,6 +1086,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public Map.@Nullable Entry floorEntry(K key) { return exportEntry(getFloorEntry(key)); } @@ -1075,6 +1098,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public @Nullable K floorKey(K key) { return keyOrNull(getFloorEntry(key)); } @@ -1086,6 +1110,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public Map.@Nullable Entry ceilingEntry(K key) { return exportEntry(getCeilingEntry(key)); } @@ -1097,6 +1122,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public @Nullable K ceilingKey(K key) { return keyOrNull(getCeilingEntry(key)); } @@ -1108,6 +1134,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public Map.@Nullable Entry higherEntry(K key) { return exportEntry(getHigherEntry(key)); } @@ -1119,6 +1146,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ + @SideEffectFree public @Nullable K higherKey(K key) { return keyOrNull(getHigherEntry(key)); } @@ -1159,6 +1187,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. It does not support the {@code add} or {@code addAll} * operations. */ + @DoesNotUnrefineReceiver("modifiability") public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1506,12 +1535,19 @@ public Iterator descendingIterator() { @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { return m.containsKey(o); } public void clear() { m.clear(); } + @Pure public E lower(E e) { return m.lowerKey(e); } + @Pure public E floor(E e) { return m.floorKey(e); } + @Pure public E ceiling(E e) { return m.ceilingKey(e); } + @Pure public E higher(E e) { return m.higherKey(e); } + @Pure public E first() { return m.firstKey(); } + @Pure public E last() { return m.lastKey(); } + @Pure public Comparator comparator() { return m.comparator(); } public E pollFirst() { Map.Entry e = m.pollFirstEntry(); @@ -2289,6 +2325,7 @@ static final class AscendingSubMap extends NavigableSubMap { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } + @Pure public Comparator comparator() { return m.comparator(); } @@ -2381,6 +2418,7 @@ static final class DescendingSubMap extends NavigableSubMap { private final Comparator reverseComparator = Collections.reverseOrder(m.comparator); + @Pure public Comparator comparator() { return reverseComparator; } @@ -2491,6 +2529,7 @@ private Object readResolve() { public SortedMap headMap(K toKey) { throw new InternalError(); } @SideEffectFree public SortedMap tailMap(K fromKey) { throw new InternalError(); } + @Pure public Comparator comparator() { throw new InternalError(); } } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 2b55d0553f94..0ac28bf313b3 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,8 +29,6 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -42,6 +40,7 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -206,7 +205,7 @@ public class TreeSet extends AbstractSet * @return an iterator over the elements in this set in ascending order */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty TreeSet this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty TreeSet this) { return m.navigableKeySet().iterator(); } @@ -216,13 +215,15 @@ public class TreeSet extends AbstractSet * @return an iterator over the elements in this set in descending order * @since 1.6 */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty TreeSet this) { + @DoesNotUnrefineReceiver("modifiability") + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty TreeSet this) { return m.descendingKeySet().iterator(); } /** * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyModifiable NavigableSet descendingSet(@PolyModifiable TreeSet this) { return new TreeSet<>(m.descendingMap()); } @@ -287,6 +288,7 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow * does not permit null elements */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable @GuardSatisfied TreeSet this, E e) { return m.put(e, PRESENT)==null; } @@ -308,6 +310,7 @@ public boolean add(@Growable @GuardSatisfied TreeSet this, E e) { * and this set uses natural ordering, or its comparator * does not permit null elements */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @GuardSatisfied TreeSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o)==PRESENT; } @@ -316,6 +319,7 @@ public boolean remove(@Shrinkable @GuardSatisfied TreeSet this, @GuardSatisfi * Removes all of the elements from this set. * The set will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied TreeSet this) { m.clear(); } @@ -331,6 +335,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeSet this) { * if any element is null and this set uses natural ordering, or * its comparator does not permit null elements */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection c) { // Use linear-time version if applicable if (m.size()==0 && c.size() > 0 && @@ -354,7 +359,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection subSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean fromInclusive, + public @PolyGrowShrink @PolyModifiable NavigableSet subSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean fromInclusive, @GuardSatisfied E toElement, boolean toInclusive) { return new TreeSet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); @@ -369,7 +374,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection headSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E toElement, boolean inclusive) { + public @PolyGrowShrink @PolyModifiable NavigableSet headSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E toElement, boolean inclusive) { return new TreeSet<>(m.headMap(toElement, inclusive)); } @@ -382,7 +387,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection tailSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean inclusive) { + public @PolyGrowShrink @PolyModifiable NavigableSet tailSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, boolean inclusive) { return new TreeSet<>(m.tailMap(fromElement, inclusive)); } @@ -394,7 +399,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection subSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement) { + public @PolyGrowShrink @PolyModifiable SortedSet subSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, @GuardSatisfied E fromElement, @GuardSatisfied E toElement) { return subSet(fromElement, true, toElement, false); } @@ -406,7 +411,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection headSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, E toElement) { + public @PolyGrowShrink @PolyModifiable SortedSet headSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, E toElement) { return headSet(toElement, false); } @@ -418,7 +423,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection tailSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, E fromElement) { + public @PolyGrowShrink @PolyModifiable SortedSet tailSet(@PolyModifiable @GuardSatisfied @PolyGrowShrink TreeSet this, E fromElement) { return tailSet(fromElement, true); } @@ -430,7 +435,7 @@ public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection this) { return m.firstKey(); } @@ -438,7 +443,7 @@ public E first(@GuardSatisfied @NonEmpty TreeSet this) { /** * @throws NoSuchElementException {@inheritDoc} */ - @SideEffectFree + @Pure public E last(@GuardSatisfied @NonEmpty TreeSet this) { return m.lastKey(); } @@ -452,6 +457,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * does not permit null elements * @since 1.6 */ + @Pure public @Nullable E lower(E e) { return m.lowerKey(e); } @@ -463,6 +469,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * does not permit null elements * @since 1.6 */ + @Pure public @Nullable E floor(E e) { return m.floorKey(e); } @@ -474,6 +481,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * does not permit null elements * @since 1.6 */ + @Pure public @Nullable E ceiling(E e) { return m.ceilingKey(e); } @@ -485,6 +493,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * does not permit null elements * @since 1.6 */ + @Pure public @Nullable E higher(E e) { return m.higherKey(e); } @@ -492,6 +501,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { /** * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@Shrinkable @GuardSatisfied TreeSet this) { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); @@ -500,6 +510,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { /** * @since 1.6 */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable @GuardSatisfied TreeSet this) { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); @@ -514,6 +525,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -527,6 +539,7 @@ public void addFirst(E e) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { throw new UnsupportedOperationException(); } @@ -623,6 +636,7 @@ private void readObject(java.io.ObjectInputStream s) * @return a {@code Spliterator} over the elements in this set * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public Spliterator spliterator() { return TreeMap.keySpliteratorFor(m); } diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 4093f4305b93..35c7c7f61bd9 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -43,6 +43,8 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -403,6 +405,7 @@ public boolean contains(@GuardSatisfied Vector this, @GuardSatisfied @Nullabl * this vector, or -1 if this vector does not contain the element */ @Pure + @StaticallyExecutable public @GTENegativeOne int indexOf(@GuardSatisfied Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return indexOf(o, 0); } @@ -424,6 +427,7 @@ public boolean contains(@GuardSatisfied Vector this, @GuardSatisfied @Nullabl * @see Object#equals(Object) */ @Pure + @StaticallyExecutable public synchronized @GTENegativeOne int indexOf(@GuardSatisfied Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o, @NonNegative int index) { if (o == null) { for (int i = index ; i < elementCount ; i++) @@ -449,6 +453,7 @@ public boolean contains(@GuardSatisfied Vector this, @GuardSatisfied @Nullabl * this vector, or -1 if this vector does not contain the element */ @Pure + @StaticallyExecutable public synchronized @GTENegativeOne int lastIndexOf(@GuardSatisfied Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return lastIndexOf(o, elementCount-1); } @@ -470,6 +475,7 @@ public boolean contains(@GuardSatisfied Vector this, @GuardSatisfied @Nullabl * than or equal to the current size of this vector */ @Pure + @StaticallyExecutable public synchronized @GTENegativeOne int lastIndexOf(@GuardSatisfied Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o, @NonNegative int index) { if (index >= elementCount) throw new IndexOutOfBoundsException(index + " >= "+ elementCount); @@ -553,6 +559,7 @@ public synchronized E lastElement(@NonEmpty Vector this) { * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void setElementAt(@Replaceable @GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + @@ -580,6 +587,7 @@ public synchronized void setElementAt(@Replaceable @GuardSatisfied Vector thi * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void removeElementAt(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + @@ -620,6 +628,7 @@ else if (index < 0) { * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index > size()}) */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void insertElementAt(@Growable @GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index @@ -648,6 +657,7 @@ public synchronized void insertElementAt(@Growable @GuardSatisfied Vector thi * * @param obj the component to be added */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void addElement(@Growable @GuardSatisfied Vector this, E obj) { modCount++; add(obj, elementData, elementCount); @@ -668,6 +678,7 @@ public synchronized void addElement(@Growable @GuardSatisfied Vector this, E * @return {@code true} if the argument was a component of this * vector; {@code false} otherwise. */ + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean removeElement(@Shrinkable @GuardSatisfied @CanShrink Vector this, Object obj) { modCount++; int i = indexOf(obj); @@ -684,6 +695,7 @@ public synchronized boolean removeElement(@Shrinkable @GuardSatisfied @CanShrink *

This method is identical in functionality to the {@link #clear} * method (which is part of the {@link List} interface). */ + @DoesNotUnrefineReceiver("modifiability") public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrink Vector this) { final Object[] es = elementData; for (int to = elementCount, i = elementCount = 0; i < to; i++) @@ -749,7 +761,6 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @throws NullPointerException if the given array is null * @since 1.2 */ - @SideEffectFree @SuppressWarnings("unchecked") public synchronized @Nullable T[] toArray(@PolyNull T[] a) { if (a.length < elementCount) @@ -803,6 +814,7 @@ public synchronized E get(@GuardSatisfied Vector this, @NonNegative int index * ({@code index < 0 || index >= size()}) * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public synchronized E set(@Replaceable @GuardSatisfied Vector this, @NonNegative int index, E element) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -833,6 +845,7 @@ private void add(E e, Object[] elementData, int s) { */ @SideEffectsOnly("this") @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean add(@Growable @GuardSatisfied Vector this, E e) { modCount++; add(e, elementData, elementCount); @@ -850,6 +863,7 @@ public synchronized boolean add(@Growable @GuardSatisfied Vector this, E e) { * @return true if the Vector contained the specified element * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeElement(o); } @@ -865,6 +879,7 @@ public boolean remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @Gu * ({@code index < 0 || index > size()}) * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public void add(@Growable @GuardSatisfied Vector this, @NonNegative int index, E element) { insertElementAt(element, index); } @@ -880,6 +895,7 @@ public void add(@Growable @GuardSatisfied Vector this, @NonNegative int index * ({@code index < 0 || index >= size()}) * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public synchronized E remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { modCount++; if (index >= elementCount) @@ -901,6 +917,7 @@ public synchronized E remove(@Shrinkable @GuardSatisfied @CanShrink Vector th * * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink Vector this) { removeAllElements(); } @@ -935,6 +952,7 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa * @throws NullPointerException if the specified collection is null * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable @GuardSatisfied Vector this, Collection c) { Object[] a = c.toArray(); modCount++; @@ -969,6 +987,7 @@ public boolean addAll(@Growable @GuardSatisfied Vector this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -993,6 +1012,7 @@ public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, * or if the specified collection is null * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -1003,6 +1023,7 @@ public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, */ @SuppressWarnings({"unchecked"}) @Override + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink Vector this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1072,6 +1093,7 @@ private synchronized boolean bulkRemove(Predicate filter) { * @throws NullPointerException if the specified collection is null * @since 1.2 */ + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean addAll(@Growable @GuardSatisfied Vector this, @NonNegative int index, Collection c) { if (index < 0 || index > elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -1165,7 +1187,7 @@ public synchronized String toString(@GuardSatisfied Vector this) { * {@code (fromIndex > toIndex)} */ @SideEffectFree - public synchronized @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink Vector this, int fromIndex, int toIndex) { + public synchronized @PolyGrowShrink @PolyModifiable List subList(@PolyModifiable @GuardSatisfied @PolyGrowShrink Vector this, int fromIndex, int toIndex) { return Collections.synchronizedList(super.subList(fromIndex, toIndex), this); } @@ -1177,6 +1199,7 @@ public synchronized String toString(@GuardSatisfied Vector this) { * This call shortens the list by {@code (toIndex - fromIndex)} elements. * (If {@code toIndex==fromIndex}, this operation has no effect.) */ + @DoesNotUnrefineReceiver("modifiability") protected synchronized void removeRange(@Shrinkable @GuardSatisfied @CanShrink Vector this, int fromIndex, int toIndex) { modCount++; shiftTailOverGap(elementData, fromIndex, toIndex); @@ -1248,7 +1271,7 @@ private void writeObject(java.io.ObjectOutputStream s) * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public synchronized @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink Vector this, @NonNegative int index) { + public synchronized @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable Vector this, @NonNegative int index) { if (index < 0 || index > elementCount) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); @@ -1262,7 +1285,7 @@ private void writeObject(java.io.ObjectOutputStream s) * * @see #listIterator(int) */ - public synchronized @PolyModifiable @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyModifiable @PolyGrowShrink Vector this) { + public synchronized @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable Vector this) { return new ListItr(0); } @@ -1274,7 +1297,7 @@ private void writeObject(java.io.ObjectOutputStream s) * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public synchronized @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty Vector this) { + public synchronized @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Vector this) { return new Itr(); } @@ -1306,6 +1329,7 @@ public E next(@NonEmpty Itr this) { } } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet == -1) throw new IllegalStateException(); @@ -1354,14 +1378,17 @@ final class ListItr extends Itr implements ListIterator { cursor = index; } + @Pure public boolean hasPrevious() { return cursor != 0; } + @Pure public int nextIndex() { return cursor; } + @Pure public int previousIndex() { return cursor - 1; } @@ -1377,6 +1404,7 @@ public E previous() { } } + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastRet == -1) throw new IllegalStateException(); @@ -1386,6 +1414,7 @@ public void set(E e) { } } + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { int i = cursor; synchronized (Vector.this) { @@ -1402,6 +1431,7 @@ public void add(E e) { * @throws NullPointerException {@inheritDoc} */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void forEach(Consumer action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @@ -1418,6 +1448,7 @@ public synchronized void forEach(Consumer action) { */ @SuppressWarnings({"unchecked"}) @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(@Replaceable Vector this, UnaryOperator operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; @@ -1433,6 +1464,7 @@ public synchronized void replaceAll(@Replaceable Vector this, UnaryOperator this, Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 8f17e4c9a8c8..4efd83867b03 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -29,8 +29,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -42,6 +42,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -488,6 +489,7 @@ Entry getEntry(Object key) { * previously associated {@code null} with {@code key}.) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@Growable @Replaceable @GuardSatisfied WeakHashMap this, K key, V value) { Object k = maskNull(key); int h = hash(k); @@ -580,6 +582,7 @@ private void transfer(Entry[] src, Entry[] dest) { * @param m mappings to be stored in this map. * @throws NullPointerException if the specified map is null. */ + @DoesNotUnrefineReceiver("modifiability") public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this, Map m) { int numKeysToBeAdded = m.size(); if (numKeysToBeAdded == 0) @@ -629,6 +632,7 @@ public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this * @return the previous value associated with {@code key}, or * {@code null} if there was no mapping for {@code key} */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable V remove(@Shrinkable @GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); int h = hash(k); @@ -688,6 +692,7 @@ boolean removeMapping(Object o) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied WeakHashMap this) { // clear out ref queue. We don't need to expunge entries // since table is getting cleared. @@ -760,20 +765,24 @@ private static class Entry extends WeakReference implements Map.Ent } @SuppressWarnings("unchecked") + @Pure public K getKey() { return (K) WeakHashMap.unmaskNull(get()); } + @Pure public V getValue() { return value; } + @DoesNotUnrefineReceiver("modifiability") public V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } + @Pure public boolean equals(Object o) { if (!(o instanceof Map.Entry e)) return false; @@ -788,6 +797,7 @@ public boolean equals(Object o) { return false; } + @Pure public int hashCode() { K k = getKey(); V v = getValue(); @@ -859,6 +869,7 @@ protected Entry nextEntry() { return lastReturned; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == null) throw new IllegalStateException(); @@ -935,6 +946,7 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { if (containsKey(o)) { WeakHashMap.this.remove(o); @@ -944,6 +956,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { return false; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { WeakHashMap.this.clear(); } @@ -994,6 +1007,7 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { WeakHashMap.this.clear(); } @@ -1038,6 +1052,7 @@ && getEntry(e.getKey()) != null && getEntry(e.getKey()).equals(e); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { return removeMapping(o); } @@ -1047,6 +1062,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { return WeakHashMap.this.size(); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { WeakHashMap.this.clear(); } @@ -1063,7 +1079,6 @@ public Object[] toArray() { return deepCopy().toArray(); } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return deepCopy().toArray(a); } @@ -1076,6 +1091,7 @@ public Spliterator> spliterator() { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { Objects.requireNonNull(action); int expectedModCount = modCount; @@ -1098,6 +1114,7 @@ public void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable WeakHashMap this, BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; 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 aaa8c668f02f..6d1e38280473 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -51,6 +51,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -347,6 +348,7 @@ void removeAt(final int removeIndex) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable ArrayBlockingQueue this, E e) { return super.add(e); } @@ -360,6 +362,7 @@ public boolean add(@Growable ArrayBlockingQueue this, E e) { * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable ArrayBlockingQueue this, E e) { Objects.requireNonNull(e); final ReentrantLock lock = this.lock; @@ -383,6 +386,7 @@ public boolean offer(@Growable ArrayBlockingQueue this, E e) { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable ArrayBlockingQueue this, E e) throws InterruptedException { Objects.requireNonNull(e); final ReentrantLock lock = this.lock; @@ -404,6 +408,7 @@ public void put(@Growable ArrayBlockingQueue this, E e) throws InterruptedExc * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable ArrayBlockingQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { @@ -424,6 +429,7 @@ public boolean offer(@Growable ArrayBlockingQueue this, E e, long timeout, Ti } } + @DoesNotUnrefineReceiver("modifiability") public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -434,6 +440,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) } } + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -446,6 +453,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) } } + @DoesNotUnrefineReceiver("modifiability") public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -531,6 +539,7 @@ 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 */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink ArrayBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -682,6 +691,7 @@ public String toString() { * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -721,6 +731,7 @@ private static void circularClear(Object[] items, int i, int end) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -731,6 +742,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -783,7 +795,7 @@ else if (i > take) * * @return an iterator over the elements in this queue in proper sequence */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ArrayBlockingQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ArrayBlockingQueue this) { return new Itr(); } @@ -1296,6 +1308,7 @@ public void forEachRemaining(Consumer action) { } } + @DoesNotUnrefineReceiver("modifiability") public void remove() { final ReentrantLock lock = ArrayBlockingQueue.this.lock; lock.lock(); @@ -1497,6 +1510,7 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink ArrayBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1505,6 +1519,7 @@ public boolean removeIf(@Shrinkable @CanShrink ArrayBlockingQueue this, Predi /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink ArrayBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1513,6 +1528,7 @@ public boolean removeAll(@Shrinkable @CanShrink ArrayBlockingQueue this, Coll /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 1affce11f660..2750df4daa55 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -38,11 +38,11 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -55,6 +55,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -665,16 +666,21 @@ static class Node implements Map.Entry { this.next = next; } + @Pure public final K getKey() { return key; } + @Pure public final V getValue() { return val; } + @Pure public final int hashCode() { return key.hashCode() ^ val.hashCode(); } public final String toString() { return Helpers.mapEntryToString(key, val); } + @DoesNotUnrefineReceiver("modifiability") public final V setValue(V value) { throw new UnsupportedOperationException(); } + @Pure public final boolean equals(Object o) { Object k, v, u; Map.Entry e; return ((o instanceof Map.Entry) && @@ -1036,6 +1042,7 @@ public boolean containsValue(@GuardSatisfied @UnknownSignedness Object value) { * @throws NullPointerException if the specified key or value is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@Growable @Replaceable ConcurrentHashMap this, K key, V value) { return putVal(key, value, false); } @@ -1117,6 +1124,7 @@ else if (f instanceof ReservationNode) * * @param m mappings to be stored in this map */ + @DoesNotUnrefineReceiver("modifiability") public void putAll(@Growable @Replaceable ConcurrentHashMap this, Map m) { tryPresize(m.size()); for (Map.Entry e : m.entrySet()) @@ -1132,6 +1140,7 @@ public void putAll(@Growable @Replaceable ConcurrentHashMap this, Map this, @GuardSatisfied @UnknownSignedness Object key) { return replaceNode(key, null, null); } @@ -1217,6 +1226,7 @@ else if (f instanceof ReservationNode) /** * Removes all of the mappings from this map. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable ConcurrentHashMap this) { long delta = 0L; // negative number of deletions int i = 0; @@ -1577,6 +1587,7 @@ private void readObject(java.io.ObjectInputStream s) * @throws NullPointerException if the specified key or value is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + @DoesNotUnrefineReceiver("modifiability") public @Nullable V putIfAbsent(@Growable ConcurrentHashMap this, K key, V value) { return putVal(key, value, true); } @@ -1586,6 +1597,7 @@ private void readObject(java.io.ObjectInputStream s) * * @throws NullPointerException if the specified key is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) throw new NullPointerException(); @@ -1597,6 +1609,7 @@ public boolean remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @ * * @throws NullPointerException if any of the arguments are null */ + @DoesNotUnrefineReceiver("modifiability") public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); @@ -1610,6 +1623,7 @@ public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldVal * or {@code null} if there was no mapping for the key * @throws NullPointerException if the specified key or value is null */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable V replace(@Replaceable ConcurrentHashMap this, K key, V value) { if (key == null || value == null) throw new NullPointerException(); @@ -1635,6 +1649,7 @@ public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultVa return (v = get(key)) == null ? defaultValue : v; } + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); Node[] t; @@ -1646,6 +1661,7 @@ public void forEach(BiConsumer action) { } } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable ConcurrentHashMap this, BiFunction function) { if (function == null) throw new NullPointerException(); Node[] t; @@ -1729,6 +1745,7 @@ boolean removeValueIf(Predicate function) { * @throws RuntimeException or Error if the mappingFunction does so, * in which case the mapping is left unestablished */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(@Growable ConcurrentHashMap this, K key, Function mappingFunction) { if (key == null || mappingFunction == null) throw new NullPointerException(); @@ -1841,6 +1858,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(@Shrinkable @Replaceable ConcurrentHashMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); @@ -1935,6 +1953,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(@Modifiable ConcurrentHashMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) @@ -2064,6 +2083,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(@Modifiable ConcurrentHashMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) throw new NullPointerException(); @@ -3485,6 +3505,7 @@ static class BaseIterator extends Traverser { @Pure public final boolean hasMoreElements() { return next != null; } + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node p; if ((p = lastReturned) == null) @@ -3565,8 +3586,11 @@ public final Map.Entry next(@NonEmpty EntryIterator this) { this.val = val; this.map = map; } + @Pure public K getKey() { return key; } + @Pure public V getValue() { return val; } + @Pure public int hashCode() { return key.hashCode() ^ val.hashCode(); } public String toString() { return Helpers.mapEntryToString(key, val); @@ -3589,6 +3613,7 @@ public boolean equals(Object o) { * could even have been removed, in which case the put will * re-establish). We do not and cannot guarantee more. */ + @DoesNotUnrefineReceiver("modifiability") public V setValue(V value) { if (value == null) throw new NullPointerException(); V v = val; @@ -4480,6 +4505,7 @@ abstract static sealed class CollectionView * Removes all of the elements from this view, by removing all * the mappings from the map backing this view. */ + @DoesNotUnrefineReceiver("modifiability") public final void clear() { map.clear(); } @Pure public final int size() { return map.size(); } @@ -4502,6 +4528,7 @@ abstract static sealed class CollectionView @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public abstract boolean contains(@UnknownSignedness Object o); + @DoesNotUnrefineReceiver("modifiability") public abstract boolean remove(@UnknownSignedness Object o); private static final String OOME_MSG = "Required array size too large"; @@ -4529,7 +4556,6 @@ abstract static sealed class CollectionView return (i == n) ? r : Arrays.copyOf(r, i); } - @SideEffectFree @SuppressWarnings("unchecked") public final @Nullable T[] toArray(@PolyNull T[] a) { long sz = map.mappingCount(); @@ -4598,6 +4624,7 @@ public final boolean containsAll(Collection c) { if (c == null) throw new NullPointerException(); boolean modified = false; @@ -4620,6 +4647,7 @@ public boolean removeAll(Collection c) { if (c == null) throw new NullPointerException(); boolean modified = false; @@ -4684,6 +4712,7 @@ public final boolean retainAll(Collection iterator() { * for additions was provided */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(K e) { V v; if ((v = value) == null) @@ -4726,6 +4756,7 @@ public boolean add(K e) { * @throws UnsupportedOperationException if no default mapped value * for additions was provided */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { boolean added = false; V v; @@ -4787,6 +4818,7 @@ public final boolean contains(@UnknownSignedness Object o) { return map.containsValue(o); } + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@UnknownSignedness Object o) { if (o != null) { for (Iterator it = iterator(); it.hasNext();) { @@ -4808,9 +4840,11 @@ public final Iterator iterator() { } @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean add(V e) { throw new UnsupportedOperationException(); } + @DoesNotUnrefineReceiver("modifiability") public final boolean addAll(Collection c) { throw new UnsupportedOperationException(); } @@ -4827,6 +4861,7 @@ public final boolean addAll(Collection c) { return modified; } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return map.removeValueIf(filter); } @@ -4892,10 +4927,12 @@ public Iterator> iterator() { } @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(Entry e) { return map.putVal(e.getKey(), e.getValue(), false) == null; } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection> c) { boolean added = false; for (Entry e : c) { @@ -4905,6 +4942,7 @@ public boolean addAll(Collection> c) { return added; } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate> filter) { return map.removeEntryIf(filter); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 3e526a303926..7fce4bc51a8c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -52,6 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -846,6 +847,7 @@ private void initHeadTail(Node h, Node t) { * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { linkFirst(e); } @@ -859,6 +861,7 @@ public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable ConcurrentLinkedDeque this, E e) { linkLast(e); } @@ -870,6 +873,7 @@ public void addLast(@Growable ConcurrentLinkedDeque this, E e) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { linkFirst(e); return true; @@ -884,6 +888,7 @@ public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(@Growable ConcurrentLinkedDeque this, E e) { linkLast(e); return true; @@ -924,6 +929,7 @@ public boolean offerLast(@Growable ConcurrentLinkedDeque this, E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getFirst(@NonEmpty ConcurrentLinkedDeque this) { return screenNullResult(peekFirst()); } @@ -931,10 +937,12 @@ public E getFirst(@NonEmpty ConcurrentLinkedDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getLast(@NonEmpty ConcurrentLinkedDeque this) { return screenNullResult(peekLast()); } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { for (Node first = first(), p = first;;) { @@ -956,6 +964,7 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { } } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { for (Node last = last(), p = last;;) { @@ -980,6 +989,7 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollFirst()); } @@ -987,6 +997,7 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Concurrent /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollLast()); } @@ -1000,6 +1011,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentL * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable ConcurrentLinkedDeque this, E e) { return offerLast(e); } @@ -1013,10 +1025,12 @@ public boolean offer(@Growable ConcurrentLinkedDeque this, E e) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable ConcurrentLinkedDeque this, E e) { return offerLast(e); } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @CanShrink ConcurrentLinkedDeque this) { return pollFirst(); } @Pure public @Nullable E peek() { return peekFirst(); } @@ -1024,21 +1038,25 @@ public boolean add(@Growable ConcurrentLinkedDeque this, E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } /** * @throws NoSuchElementException {@inheritDoc} */ + @SideEffectFree public E element(@NonEmpty ConcurrentLinkedDeque this) { return getFirst(); } /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void push(@Growable ConcurrentLinkedDeque this, E e) { addFirst(e); } /** @@ -1053,6 +1071,7 @@ public boolean add(@Growable ConcurrentLinkedDeque this, E e) { * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); for (Node p = first(); p != null; p = succ(p)) { @@ -1079,6 +1098,7 @@ public boolean removeFirstOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDequ * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); for (Node p = last(); p != null; p = pred(p)) { @@ -1171,6 +1191,7 @@ public int size() { * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedDeque this, @GuardSatisfied @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -1187,6 +1208,7 @@ public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedDeque this, @Gua * of its elements are null * @throws IllegalArgumentException if the collection is this deque */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable ConcurrentLinkedDeque this, Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll @@ -1241,6 +1263,7 @@ else if (p.prev == p) // NEXT_TERMINATOR /** * Removes all of the elements from this deque. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { while (pollFirst() != null) ; @@ -1357,7 +1380,6 @@ else if (a != null && size <= a.length) { * this deque * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { if (a == null) throw new NullPointerException(); @@ -1374,7 +1396,7 @@ else if (a != null && size <= a.length) { * @return an iterator over the elements in this deque in proper sequence */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentLinkedDeque this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentLinkedDeque this) { return new Itr(); } @@ -1388,7 +1410,7 @@ else if (a != null && size <= a.length) { * * @return an iterator over the elements in this deque in reverse order */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentLinkedDeque this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentLinkedDeque this) { return new DescendingItr(); } @@ -1457,6 +1479,7 @@ public E next(@NonEmpty AbstractItr this) { return item; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node l = lastRet; if (l == null) throw new IllegalStateException(); @@ -1642,6 +1665,7 @@ private void readObject(java.io.ObjectInputStream s) /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1650,6 +1674,7 @@ public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Pr /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1658,6 +1683,7 @@ public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedDeque this, C /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index b24e1d8d588d..1e289de70597 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -51,6 +51,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -302,6 +303,7 @@ boolean casItem(E cmp, E val) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable ConcurrentLinkedQueue this, E e) { return offer(e); } @@ -374,6 +376,7 @@ private Node skipDeadNodes(Node pred, Node c, Node p, Node q) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable ConcurrentLinkedQueue this, E e) { final Node newNode = new Node(Objects.requireNonNull(e)); @@ -403,6 +406,7 @@ else if (p == q) } } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { restartFromHead: for (;;) { for (Node h = head, p = h, q;; p = q) { @@ -547,6 +551,7 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedQueue this, @GuardSatisfied @UnknownSignedness Object o) { if (o == null) return false; restartFromHead: for (;;) { @@ -583,6 +588,7 @@ public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedQueue this, @Gua * of its elements are null * @throws IllegalArgumentException if the collection is this queue */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable ConcurrentLinkedQueue this, Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll @@ -740,7 +746,6 @@ else if (a != null && size <= a.length) { * this queue * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { Objects.requireNonNull(a); @@ -757,7 +762,7 @@ else if (a != null && size <= a.length) { * @return an iterator over the elements in this queue in proper sequence */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentLinkedQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentLinkedQueue this) { return new Itr(); } @@ -829,6 +834,7 @@ public E next(@NonEmpty Itr this) { // Default implementation of forEachRemaining is "good enough". + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node l = lastRet; if (l == null) throw new IllegalStateException(); @@ -995,6 +1001,7 @@ public Spliterator spliterator() { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1003,6 +1010,7 @@ public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Pr /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1011,11 +1019,13 @@ public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedQueue this, C /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { bulkRemove(e -> true); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 8397bc488ab4..765bfdf01198 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -37,13 +37,13 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.Unmodifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.ThrowsUOE; +import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; @@ -52,6 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -1332,6 +1333,7 @@ public boolean containsKey(@GuardSatisfied @UnknownSignedness Object key) { * with the keys currently in the map * @throws NullPointerException if the specified key is null */ + @Pure public V get(Object key) { return doGet(key); } @@ -1366,6 +1368,7 @@ public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultVa * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ + @DoesNotUnrefineReceiver("modifiability") public V put(@Growable @Replaceable ConcurrentSkipListMap this, K key, V value) { if (value == null) throw new NullPointerException(); @@ -1382,6 +1385,7 @@ public V put(@Growable @Replaceable ConcurrentSkipListMap this, K key, V va * with the keys currently in the map * @throws NullPointerException if the specified key is null */ + @DoesNotUnrefineReceiver("modifiability") public V remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key) { return doRemove(key, null); } @@ -1437,6 +1441,7 @@ public boolean isEmpty() { /** * Removes all of the mappings from this map. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable ConcurrentSkipListMap this) { Index h, r, d; Node b; VarHandle.acquireFence(); @@ -1482,6 +1487,7 @@ else if ((d = h.down) != null) // remove levels * or the mappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(@Growable ConcurrentSkipListMap this, K key, Function mappingFunction) { if (key == null || mappingFunction == null) @@ -1506,6 +1512,7 @@ else if ((d = h.down) != null) // remove levels * or the remappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(@Shrinkable @Replaceable ConcurrentSkipListMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) @@ -1538,6 +1545,7 @@ else if (doRemove(key, v) != null) * or the remappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(@Modifiable ConcurrentSkipListMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) @@ -1577,6 +1585,7 @@ else if (doRemove(key, v) != null) * or the remappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(@Modifiable ConcurrentSkipListMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) @@ -1816,6 +1825,7 @@ public boolean equals(@Nullable Object o) { * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(@Growable ConcurrentSkipListMap this, K key, V value) { if (value == null) throw new NullPointerException(); @@ -1829,6 +1839,7 @@ public V putIfAbsent(@Growable ConcurrentSkipListMap this, K key, V value) * with the keys currently in the map * @throws NullPointerException if the specified key is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) throw new NullPointerException(); @@ -1842,6 +1853,7 @@ public boolean remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfi * with the keys currently in the map * @throws NullPointerException if any of the arguments are null */ + @DoesNotUnrefineReceiver("modifiability") public boolean replace(@Replaceable ConcurrentSkipListMap this, K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); @@ -1867,6 +1879,7 @@ public boolean replace(@Replaceable ConcurrentSkipListMap this, K key, V ol * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ + @DoesNotUnrefineReceiver("modifiability") public V replace(@Replaceable ConcurrentSkipListMap this, K key, V value) { if (key == null || value == null) throw new NullPointerException(); @@ -1881,6 +1894,7 @@ public V replace(@Replaceable ConcurrentSkipListMap this, K key, V value) { /* ------ SortedMap API methods ------ */ + @Pure public Comparator comparator() { return comparator; } @@ -1888,6 +1902,7 @@ public Comparator comparator() { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public K firstKey(@NonEmpty ConcurrentSkipListMap this) { Node n = findFirst(); if (n == null) @@ -1898,6 +1913,7 @@ public K firstKey(@NonEmpty ConcurrentSkipListMap this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public K lastKey(@NonEmpty ConcurrentSkipListMap this) { Node n = findLast(); if (n == null) @@ -1914,6 +1930,7 @@ public K lastKey(@NonEmpty ConcurrentSkipListMap this) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -1927,6 +1944,7 @@ public V putFirst(K k, V v) { * @since 21 */ @ThrowsUOE + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -2016,6 +2034,7 @@ public V putLast(K k, V v) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public Map.@Unmodifiable Entry lowerEntry(K key) { return findNearEntry(key, LT, comparator); } @@ -2024,6 +2043,7 @@ public V putLast(K k, V v) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public K lowerKey(K key) { Node n = findNear(key, LT, comparator); return (n == null) ? null : n.key; @@ -2039,6 +2059,7 @@ public K lowerKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public Map.@Unmodifiable Entry floorEntry(K key) { return findNearEntry(key, LT|EQ, comparator); } @@ -2048,6 +2069,7 @@ public K lowerKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public K floorKey(K key) { Node n = findNear(key, LT|EQ, comparator); return (n == null) ? null : n.key; @@ -2062,6 +2084,7 @@ public K floorKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public Map.@Unmodifiable Entry ceilingEntry(K key) { return findNearEntry(key, GT|EQ, comparator); } @@ -2070,6 +2093,7 @@ public K floorKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public K ceilingKey(K key) { Node n = findNear(key, GT|EQ, comparator); return (n == null) ? null : n.key; @@ -2085,6 +2109,7 @@ public K ceilingKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public Map.@Unmodifiable Entry higherEntry(K key) { return findNearEntry(key, GT, comparator); } @@ -2094,6 +2119,7 @@ public K ceilingKey(K key) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if the specified key is null */ + @Pure public K higherKey(K key) { Node n = findNear(key, GT, comparator); return (n == null) ? null : n.key; @@ -2105,6 +2131,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ + @Pure public Map.@Unmodifiable Entry firstEntry() { return findFirstEntry(); } @@ -2115,6 +2142,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ + @Pure public Map.@Unmodifiable Entry lastEntry() { return findLastEntry(); } @@ -2125,6 +2153,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ + @DoesNotUnrefineReceiver("modifiability") public Map.@Unmodifiable Entry pollFirstEntry(@Shrinkable ConcurrentSkipListMap this) { return doRemoveFirstEntry(); } @@ -2135,6 +2164,7 @@ public K higherKey(K key) { * The returned entry does not support * the {@code Entry.setValue} method. */ + @DoesNotUnrefineReceiver("modifiability") public Map.@Unmodifiable Entry pollLastEntry(@Shrinkable ConcurrentSkipListMap this) { return doRemoveLastEntry(); } @@ -2175,6 +2205,7 @@ final void advance(Node b) { next = n; } + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node n; K k; if ((n = lastReturned) == null || (k = n.key) == null) @@ -2247,19 +2278,30 @@ static final class KeySet @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { return m.containsKey(o); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { return m.remove(o) != null; } + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } + @Pure public K lower(K e) { return m.lowerKey(e); } + @Pure public K floor(K e) { return m.floorKey(e); } + @Pure public K ceiling(K e) { return m.ceilingKey(e); } + @Pure public K higher(K e) { return m.higherKey(e); } + @Pure public Comparator comparator() { return m.comparator(); } + @Pure public K first() { return m.firstKey(); } + @Pure public K last() { return m.lastKey(); } + @DoesNotUnrefineReceiver("modifiability") public K pollFirst() { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } + @DoesNotUnrefineReceiver("modifiability") public K pollLast() { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); @@ -2337,6 +2379,7 @@ public Iterator iterator() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { return m.containsValue(o); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } public Object[] toArray() { return toList(this).toArray(); } public @Nullable T[] toArray(@PolyNull T[] a) { return toList(this).toArray(a); } @@ -2347,6 +2390,7 @@ public Spliterator spliterator() { : ((SubMap)m).new SubMapValueIterator(); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) @@ -2385,6 +2429,7 @@ public boolean contains(@UnknownSignedness Object o) { V v = m.get(e.getKey()); return v != null && v.equals(e.getValue()); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry)) return false; @@ -2401,6 +2446,7 @@ public boolean isEmpty() { public int size() { return m.size(); } + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } @@ -2424,6 +2470,7 @@ public Spliterator> spliterator() { ? ((ConcurrentSkipListMap)m).entrySpliterator() : ((SubMap)m).new SubMapEntryIterator(); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate> filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) @@ -2705,16 +2752,19 @@ public boolean containsKey(@UnknownSignedness Object key) { return inBounds(key, m.comparator) && m.containsKey(key); } + @Pure public V get(Object key) { if (key == null) throw new NullPointerException(); return (!inBounds(key, m.comparator)) ? null : m.get(key); } + @DoesNotUnrefineReceiver("modifiability") public V put(@Growable @Replaceable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); return m.put(key, value); } + @DoesNotUnrefineReceiver("modifiability") public V remove(@Shrinkable SubMap this, Object key) { return (!inBounds(key, m.comparator)) ? null : m.remove(key); } @@ -2754,6 +2804,7 @@ public boolean containsValue(@UnknownSignedness Object value) { return false; } + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable SubMap this) { Comparator cmp = m.comparator; for (ConcurrentSkipListMap.Node n = loNode(cmp); @@ -2766,20 +2817,24 @@ public void clear(@Shrinkable SubMap this) { /* ---------------- ConcurrentMap API methods -------------- */ + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(@Growable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); return m.putIfAbsent(key, value); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable SubMap this, @UnknownSignedness Object key, @UnknownSignedness Object value) { return inBounds(key, m.comparator) && m.remove(key, value); } + @DoesNotUnrefineReceiver("modifiability") public boolean replace(@Replaceable SubMap this, K key, V oldValue, V newValue) { checkKeyBounds(key, m.comparator); return m.replace(key, oldValue, newValue); } + @DoesNotUnrefineReceiver("modifiability") public V replace(@Replaceable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); return m.replace(key, value); @@ -2787,6 +2842,7 @@ public V replace(@Replaceable SubMap this, K key, V value) { /* ---------------- SortedMap API methods -------------- */ + @Pure public Comparator comparator() { Comparator cmp = m.comparator(); if (isDescending) @@ -2881,58 +2937,72 @@ SubMap newSubMap(K fromKey, boolean fromInclusive, /* ---------------- Relational methods -------------- */ + @Pure public Map.Entry ceilingEntry(K key) { return getNearEntry(key, GT|EQ); } + @Pure public K ceilingKey(K key) { return getNearKey(key, GT|EQ); } + @Pure public Map.Entry lowerEntry(K key) { return getNearEntry(key, LT); } + @Pure public K lowerKey(K key) { return getNearKey(key, LT); } + @Pure public Map.Entry floorEntry(K key) { return getNearEntry(key, LT|EQ); } + @Pure public K floorKey(K key) { return getNearKey(key, LT|EQ); } + @Pure public Map.Entry higherEntry(K key) { return getNearEntry(key, GT); } + @Pure public K higherKey(K key) { return getNearKey(key, GT); } + @Pure public K firstKey() { return isDescending ? highestKey() : lowestKey(); } + @Pure public K lastKey() { return isDescending ? lowestKey() : highestKey(); } + @Pure public Map.Entry firstEntry() { return isDescending ? highestEntry() : lowestEntry(); } + @Pure public Map.Entry lastEntry() { return isDescending ? lowestEntry() : highestEntry(); } + @DoesNotUnrefineReceiver("modifiability") public Map.Entry pollFirstEntry(@Shrinkable SubMap this) { return isDescending ? removeHighest() : removeLowest(); } + @DoesNotUnrefineReceiver("modifiability") public Map.Entry pollLastEntry(@Shrinkable SubMap this) { return isDescending ? removeLowest() : removeHighest(); } @@ -3050,6 +3120,7 @@ private void descend() { } } + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node l = lastReturned; if (l == null) @@ -3122,6 +3193,7 @@ public int characteristics() { // default Map method overrides + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); Node b, n; V v; @@ -3134,6 +3206,7 @@ public void forEach(BiConsumer action) { } } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable ConcurrentSkipListMap this, BiFunction function) { if (function == null) throw new NullPointerException(); Node b, n; V v; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 6c7b5d3eb1f5..a458a08cdcd2 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -50,6 +50,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -266,6 +267,7 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable ConcurrentSkipListSet this, E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; } @@ -284,6 +286,7 @@ public boolean add(@Growable ConcurrentSkipListSet this, E e) { * with the elements currently in this set * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable ConcurrentSkipListSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o, Boolean.TRUE); } @@ -291,6 +294,7 @@ public boolean remove(@Shrinkable ConcurrentSkipListSet this, @GuardSatisfied /** * Removes all of the elements from this set. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable ConcurrentSkipListSet this) { m.clear(); } @@ -301,7 +305,7 @@ public void clear(@Shrinkable ConcurrentSkipListSet this) { * @return an iterator over the elements in this set in ascending order */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this) { return m.navigableKeySet().iterator(); } @@ -310,7 +314,7 @@ public void clear(@Shrinkable ConcurrentSkipListSet this) { * * @return an iterator over the elements in this set in descending order */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this) { return m.descendingKeySet().iterator(); } @@ -359,6 +363,7 @@ public boolean equals(@Nullable Object o) { * @throws NullPointerException if the specified collection or any * of its elements are null */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable ConcurrentSkipListSet this, Collection c) { // Override AbstractSet version to avoid unnecessary call to size() boolean modified = false; @@ -374,6 +379,7 @@ public boolean removeAll(@Shrinkable ConcurrentSkipListSet this, Collection this) { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable ConcurrentSkipListSet this) { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); @@ -423,6 +434,7 @@ public E higher(E e) { /** * @throws java.util.NoSuchElementException {@inheritDoc} */ + @Pure public E first(@NonEmpty ConcurrentSkipListSet this) { return m.firstKey(); } @@ -430,6 +442,7 @@ public E first(@NonEmpty ConcurrentSkipListSet this) { /** * @throws java.util.NoSuchElementException {@inheritDoc} */ + @Pure public E last(@NonEmpty ConcurrentSkipListSet this) { return m.lastKey(); } @@ -466,7 +479,7 @@ public void addLast(E e) { * {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet subSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { @@ -480,7 +493,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement, boolean inclusive) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet headSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this, E toElement, boolean inclusive) { return new ConcurrentSkipListSet(m.headMap(toElement, inclusive)); } @@ -489,7 +502,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code fromElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean inclusive) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet tailSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean inclusive) { return new ConcurrentSkipListSet(m.tailMap(fromElement, inclusive)); } @@ -499,7 +512,7 @@ public void addLast(E e) { * {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, E toElement) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet subSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } @@ -508,7 +521,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet headSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this, E toElement) { return headSet(toElement, false); } @@ -517,7 +530,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code fromElement} is null * @throws IllegalArgumentException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet tailSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this, E fromElement) { return tailSet(fromElement, true); } @@ -533,7 +546,7 @@ public void addLast(E e) { * * @return a reverse order view of this set */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty NavigableSet descendingSet(@PolyModifiable @PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet descendingSet(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ConcurrentSkipListSet this) { return new ConcurrentSkipListSet(m.descendingMap()); } 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 0ea4fa62040d..ac683901d348 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -53,6 +53,8 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -268,6 +270,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { /** * {@inheritDoc} */ + @Pure + @StaticallyExecutable public int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] es = getArray(); return indexOfRange(o, es, 0, es.length); @@ -288,6 +292,8 @@ public int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * {@code -1} if the element is not found. * @throws IndexOutOfBoundsException if the specified index is negative */ + @Pure + @StaticallyExecutable public int indexOf(E e, int index) { Object[] es = getArray(); return indexOfRange(e, es, index, es.length); @@ -296,6 +302,8 @@ public int indexOf(E e, int index) { /** * {@inheritDoc} */ + @Pure + @StaticallyExecutable public int lastIndexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] es = getArray(); return lastIndexOfRange(o, es, 0, es.length); @@ -317,6 +325,8 @@ public int lastIndexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @throws IndexOutOfBoundsException if the specified index is greater * than or equal to the current size of this list */ + @Pure + @StaticallyExecutable public int lastIndexOf(E e, int index) { Object[] es = getArray(); return lastIndexOfRange(e, es, 0, index + 1); @@ -357,6 +367,7 @@ public int lastIndexOf(E e, int index) { * * @return an array containing all the elements in this list */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(CopyOnWriteArrayList<@PolyNull @PolySigned E> this) { return getArray().clone(); } @@ -429,6 +440,7 @@ static String outOfBounds(int index, int size) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + @Pure public E get(int index) { return elementAt(getArray(), index); } @@ -439,6 +451,7 @@ public E get(int index) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getFirst() { Object[] es = getArray(); if (es.length == 0) @@ -453,6 +466,7 @@ public E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getLast() { Object[] es = getArray(); if (es.length == 0) @@ -467,6 +481,7 @@ public E getLast() { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { Object[] es = getArray(); @@ -489,6 +504,7 @@ public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { * @return {@code true} (as specified by {@link Collection#add}) */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { Object[] es = getArray(); @@ -507,6 +523,7 @@ public boolean add(@Growable CopyOnWriteArrayList this, E e) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void add(@Growable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { Object[] es = getArray(); @@ -533,6 +550,7 @@ public void add(@Growable CopyOnWriteArrayList this, int index, E element) { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable CopyOnWriteArrayList this, E e) { add(0, e); } @@ -542,6 +560,7 @@ public void addFirst(@Growable CopyOnWriteArrayList this, E e) { * * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { add(getArray().length, e); @@ -555,6 +574,7 @@ public void addLast(@Growable CopyOnWriteArrayList this, E e) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { synchronized (lock) { Object[] es = getArray(); @@ -581,6 +601,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList t * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { if (getArray().length == 0) @@ -596,6 +617,7 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWrit * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { int size = getArray().length; @@ -618,6 +640,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWrite * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] snapshot = getArray(); int index = indexOfRange(o, snapshot, 0, snapshot.length); @@ -698,6 +721,7 @@ void removeRange(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int fr * @param e element to be added to this list, if absent * @return {@code true} if the element was added */ + @DoesNotUnrefineReceiver("modifiability") public boolean addIfAbsent(@Growable CopyOnWriteArrayList this, E e) { Object[] snapshot = getArray(); return indexOfRange(e, snapshot, 0, snapshot.length) < 0 @@ -766,6 +790,7 @@ public boolean containsAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -787,6 +812,7 @@ public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Co * or if the specified collection is null * @see #remove(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -803,6 +829,7 @@ public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArray * @throws NullPointerException if the specified collection is null * @see #addIfAbsent(Object) */ + @DoesNotUnrefineReceiver("modifiability") public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = c.toArray(); if (c.getClass() != ArrayList.class) { @@ -834,6 +861,7 @@ public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection this) { synchronized (lock) { setArray(new Object[0]); @@ -850,6 +878,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList * @throws NullPointerException if the specified collection is null * @see #add(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? ((CopyOnWriteArrayList)c).getArray() : c.toArray(); @@ -887,6 +916,7 @@ public boolean addAll(@Growable CopyOnWriteArrayList this, Collection this, int index, Collection c) { Object[] cs = c.toArray(); synchronized (lock) { @@ -927,6 +957,7 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink CopyOnWriteArrayList this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -984,6 +1015,7 @@ boolean bulkRemove(Predicate filter, int i, int end) { } } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(@Replaceable CopyOnWriteArrayList this, UnaryOperator operator) { synchronized (lock) { replaceAllRange(operator, 0, getArray().length); @@ -999,6 +1031,7 @@ void replaceAllRange(UnaryOperator operator, int i, int end) { setArray(es); } + @DoesNotUnrefineReceiver("modifiability") public void sort(@Replaceable CopyOnWriteArrayList this, Comparator c) { synchronized (lock) { sortRange(c, 0, getArray().length); @@ -1245,6 +1278,7 @@ public int previousIndex() { * @throws UnsupportedOperationException always; {@code remove} * is not supported by this iterator. */ + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } @@ -1254,6 +1288,7 @@ public void remove() { * @throws UnsupportedOperationException always; {@code set} * is not supported by this iterator. */ + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { throw new UnsupportedOperationException(); } @@ -1263,6 +1298,7 @@ public void set(E e) { * @throws UnsupportedOperationException always; {@code add} * is not supported by this iterator. */ + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { throw new UnsupportedOperationException(); } @@ -1293,7 +1329,7 @@ public void forEachRemaining(Consumer action) { * @return a view of the specified range within this list * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyModifiable @PolyGrowShrink List subList(@PolyModifiable @PolyGrowShrink CopyOnWriteArrayList this, int fromIndex, int toIndex) { + public @PolyGrowShrink @PolyModifiable List subList(@PolyGrowShrink @PolyModifiable CopyOnWriteArrayList this, int fromIndex, int toIndex) { synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -1345,6 +1381,7 @@ private void rangeCheckForAdd(int index) { throw new IndexOutOfBoundsException(outOfBounds(index, size)); } + @SideEffectFree public Object[] toArray() { final Object[] es; final int offset; @@ -1378,6 +1415,8 @@ public Object[] toArray() { } } + @Pure + @StaticallyExecutable public int indexOf(Object o) { final Object[] es; final int offset; @@ -1391,6 +1430,8 @@ public int indexOf(Object o) { return (i == -1) ? -1 : i - offset; } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { final Object[] es; final int offset; @@ -1428,6 +1469,7 @@ public boolean containsAll(Collection c) { synchronized (lock) { final Object[] oldArray = getArrayChecked(); @@ -1555,6 +1608,7 @@ public boolean addAll(Collection c) { } } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { synchronized (lock) { rangeCheckForAdd(index); @@ -1566,6 +1620,7 @@ public boolean addAll(int index, Collection c) { } } + @DoesNotUnrefineReceiver("modifiability") public void clear() { synchronized (lock) { checkForComodification(); @@ -1575,6 +1630,7 @@ public void clear() { } } + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { synchronized (lock) { rangeCheck(index); @@ -1586,6 +1642,7 @@ public E remove(int index) { } } + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { synchronized (lock) { if (size == 0) @@ -1595,6 +1652,7 @@ public E removeFirst() { } } + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { synchronized (lock) { if (size == 0) @@ -1604,6 +1662,7 @@ public E removeLast() { } } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { synchronized (lock) { checkForComodification(); @@ -1653,6 +1712,7 @@ public void forEach(Consumer action) { action.accept(elementAt(es, i)); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { synchronized (lock) { checkForComodification(); @@ -1661,6 +1721,7 @@ public void replaceAll(UnaryOperator operator) { } } + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { synchronized (lock) { checkForComodification(); @@ -1669,16 +1730,19 @@ public void sort(Comparator c) { } } + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1732,6 +1796,7 @@ public E next(@NonEmpty COWSubListIterator this) { throw new NoSuchElementException(); } + @Pure public boolean hasPrevious() { return previousIndex() >= 0; } @@ -1783,7 +1848,7 @@ public void forEachRemaining(Consumer action) { * * @since 21 */ - public @PolyModifiable @PolyGrowShrink List reversed(@PolyModifiable @PolyGrowShrink CopyOnWriteArrayList this) { + public @PolyGrowShrink @PolyModifiable List reversed(@PolyGrowShrink @PolyModifiable CopyOnWriteArrayList this) { return new Reversed<>(this, lock); } @@ -1808,6 +1873,7 @@ class DescendingIterator implements Iterator { } public boolean hasNext() { return it.hasPrevious(); } public E next() { return it.previous(); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { it.remove(); } } @@ -1832,6 +1898,7 @@ public E next() { return it.previous(); } + @Pure public boolean hasPrevious() { return it.hasNext(); } @@ -1879,11 +1946,13 @@ public Spliterator spliterator() { // ========== Collection ========== + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { base.add(0, e); return true; } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { @SuppressWarnings("unchecked") E[] es = (E[]) c.toArray(); @@ -1896,19 +1965,23 @@ public boolean addAll(Collection c) { } } + @DoesNotUnrefineReceiver("modifiability") public void clear() { base.clear(); } + @Pure public boolean contains(Object o) { return base.contains(o); } + @Pure public boolean containsAll(Collection c) { return base.containsAll(c); } // copied from AbstractList + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -1927,6 +2000,7 @@ public boolean equals(Object o) { } // copied from AbstractList + @Pure public int hashCode() { int hashCode = 1; for (E e : this) @@ -1934,6 +2008,7 @@ public int hashCode() { return hashCode; } + @Pure public boolean isEmpty() { return base.isEmpty(); } @@ -1942,6 +2017,7 @@ public Stream parallelStream() { return StreamSupport.stream(spliterator(), true); } + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object o) { synchronized (lock) { int index = indexOf(o); @@ -1952,14 +2028,17 @@ public boolean remove(Object o) { } } + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return base.removeAll(c); } + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return base.retainAll(c); } + @Pure public int size() { return base.size(); } @@ -1968,6 +2047,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -1978,6 +2058,7 @@ public T[] toArray(T[] a) { return toArray(i -> (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), i)); } + @SideEffectFree public T[] toArray(IntFunction generator) { return ArraysSupport.reverse(base.toArray(generator)); } @@ -2001,20 +2082,24 @@ public String toString() { // ========== List ========== + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { synchronized (lock) { base.add(base.size() - index, element); } } + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { base.add(e); } + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { base.add(0, e); } + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { @SuppressWarnings("unchecked") E[] es = (E[]) c.toArray(); @@ -2029,12 +2114,14 @@ public boolean addAll(int index, Collection c) { } } + @Pure public E get(int i) { synchronized (lock) { return base.get(base.size() - i - 1); } } + @Pure public E getFirst() { synchronized (lock) { int size = base.size(); @@ -2045,6 +2132,7 @@ public E getFirst() { } } + @Pure public E getLast() { synchronized (lock) { if (base.size() == 0) @@ -2054,6 +2142,8 @@ public E getLast() { } } + @Pure + @StaticallyExecutable public int indexOf(Object o) { synchronized (lock) { int i = base.lastIndexOf(o); @@ -2061,6 +2151,8 @@ public int indexOf(Object o) { } } + @Pure + @StaticallyExecutable public int lastIndexOf(Object o) { synchronized (lock) { int i = base.indexOf(o); @@ -2076,12 +2168,14 @@ public ListIterator listIterator(int index) { return new DescendingListIterator(index); } + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { synchronized (lock) { return base.remove(base.size() - index - 1); } } + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { synchronized (lock) { int size = base.size(); @@ -2092,6 +2186,7 @@ public E removeFirst() { } } + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { synchronized (lock) { if (base.size() == 0) @@ -2101,18 +2196,22 @@ public E removeLast() { } } + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return base.removeIf(filter); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { base.replaceAll(operator); } + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { base.sort(Collections.reverseOrder(c)); } + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { synchronized (lock) { return base.set(base.size() - index - 1, element); 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 f2a816bad2c0..84c58335c031 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -51,6 +51,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -199,6 +200,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * * @return an array containing all the elements in this set */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(CopyOnWriteArraySet<@PolyNull @PolySigned E> this) { return al.toArray(); } @@ -252,6 +254,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * Removes all of the elements from this set. * The set will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable CopyOnWriteArraySet this) { al.clear(); } @@ -267,6 +270,7 @@ public void clear(@Shrinkable CopyOnWriteArraySet this) { * @param o object to be removed from this set, if present * @return {@code true} if this set contained the specified element */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable CopyOnWriteArraySet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return al.remove(o); } @@ -284,6 +288,7 @@ public boolean remove(@Shrinkable CopyOnWriteArraySet this, @GuardSatisfied @ * element */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable CopyOnWriteArraySet this, E e) { return al.addIfAbsent(e); } @@ -354,6 +359,7 @@ private static int compareSets(Object[] snapshot, Set set) { * @throws NullPointerException if the specified collection is null * @see #add(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable CopyOnWriteArraySet this, Collection c) { return al.addAllAbsent(c) > 0; } @@ -375,6 +381,7 @@ public boolean addAll(@Growable CopyOnWriteArraySet this, Collection this, Collection c) { return al.removeAll(c); } @@ -398,6 +405,7 @@ public boolean removeAll(@Shrinkable CopyOnWriteArraySet this, Collection this, Collection c) { return al.retainAll(c); } @@ -444,6 +452,7 @@ public boolean equals(@Nullable Object o) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable CopyOnWriteArraySet this, Predicate filter) { return al.removeIf(filter); } diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 485450ec1dee..6369edd3dc28 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -47,6 +47,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; @@ -174,6 +175,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable DelayQueue this, E e) { return offer(e); } @@ -185,6 +187,7 @@ public boolean add(@Growable DelayQueue this, E e) { * @return {@code true} * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable DelayQueue this, E e) { final ReentrantLock lock = this.lock; lock.lock(); @@ -207,6 +210,7 @@ public boolean offer(@Growable DelayQueue this, E e) { * @param e the element to add * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable DelayQueue this, E e) { offer(e); } @@ -221,6 +225,7 @@ public void put(@Growable DelayQueue this, E e) { * @return {@code true} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable DelayQueue this, E e, long timeout, TimeUnit unit) { return offer(e); } @@ -233,6 +238,7 @@ public boolean offer(@Growable DelayQueue this, E e, long timeout, TimeUnit u * @return the expired head of this queue, or {@code null} if this * queue has no elements with an expired delay */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -254,6 +260,7 @@ public boolean offer(@Growable DelayQueue this, E e, long timeout, TimeUnit u * @return the expired head of this queue * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -299,6 +306,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) throws * an expired delay becomes available * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -349,6 +357,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) throws * @throws NoSuchElementException if this queue has no elements with an * expired delay */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable DelayQueue this) { return super.remove(); } @@ -390,6 +399,7 @@ public int size() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -400,6 +410,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @G * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -430,6 +441,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @G * Elements with an unexpired delay are not waited for; they are * simply discarded from the queue. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -509,7 +521,6 @@ public int remainingCapacity() { * this queue * @throws NullPointerException if the specified array is null */ - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { final ReentrantLock lock = this.lock; lock.lock(); @@ -524,6 +535,7 @@ public int remainingCapacity() { * Removes a single instance of the specified element from this * queue, if it is present, whether or not it has expired. */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink DelayQueue this, @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; lock.lock(); @@ -563,7 +575,7 @@ void removeEQ(Object o) { * @return an iterator over the elements in this queue */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty DelayQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty DelayQueue this) { return new Itr(toArray()); } @@ -594,6 +606,7 @@ public E next(@NonEmpty Itr this) { return (E)array[lastRet = cursor++]; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); 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 cd6a48a92b7a..2e4550f519d6 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -51,7 +51,9 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -335,6 +337,7 @@ void unlink(@CanShrink LinkedBlockingDeque this, Node x) { * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@Growable LinkedBlockingDeque this, E e) { if (!offerFirst(e)) throw new IllegalStateException("Deque full"); @@ -344,6 +347,7 @@ public void addFirst(@Growable LinkedBlockingDeque this, E e) { * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!offerLast(e)) throw new IllegalStateException("Deque full"); @@ -352,6 +356,7 @@ public void addLast(@Growable LinkedBlockingDeque this, E e) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -367,6 +372,7 @@ public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -383,6 +389,7 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void putFirst(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -400,6 +407,7 @@ public void putFirst(@Growable LinkedBlockingDeque this, E e) throws Interrup * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void putLast(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -417,6 +425,7 @@ public void putLast(@Growable LinkedBlockingDeque this, E e) throws Interrupt * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); @@ -440,6 +449,7 @@ public boolean offerFirst(@Growable LinkedBlockingDeque this, E e, long timeo * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); @@ -462,6 +472,7 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeou /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollFirst(); if (x == null) throw new NoSuchElementException(); @@ -471,12 +482,14 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBloc /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollLast(); if (x == null) throw new NoSuchElementException(); return x; } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -487,6 +500,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlock } } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -497,6 +511,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlock } } + @DoesNotUnrefineReceiver("modifiability") public E takeFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lock(); @@ -510,6 +525,7 @@ public E takeFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque } } + @DoesNotUnrefineReceiver("modifiability") public E takeLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lock(); @@ -523,6 +539,7 @@ public E takeLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque } } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); @@ -541,6 +558,7 @@ public E takeLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque } } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); @@ -599,6 +617,7 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { } } + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -616,6 +635,7 @@ public boolean removeFirstOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque< } } + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -646,6 +666,7 @@ public boolean removeLastOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, E e) { addLast(e); return true; @@ -654,6 +675,7 @@ public boolean add(@Growable LinkedBlockingDeque this, E e) { /** * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedBlockingDeque this, E e) { return offerLast(e); } @@ -662,6 +684,7 @@ public boolean offer(@Growable LinkedBlockingDeque this, E e) { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { putLast(e); } @@ -670,6 +693,7 @@ public void put(@Growable LinkedBlockingDeque this, E e) throws InterruptedEx * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { return offerLast(e, timeout, unit); @@ -685,18 +709,22 @@ public boolean offer(@Growable LinkedBlockingDeque this, E e, long timeout, T * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { return pollFirst(); } + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { return takeFirst(); } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { return pollFirst(timeout, unit); } @@ -711,6 +739,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + @SideEffectFree public E element(@NonEmpty LinkedBlockingDeque this) { return getFirst(); } @@ -747,6 +776,7 @@ public int remainingCapacity() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -757,6 +787,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -783,6 +814,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void push(@Growable LinkedBlockingDeque this, E e) { addFirst(e); } @@ -790,6 +822,7 @@ public void push(@Growable LinkedBlockingDeque this, E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); } @@ -810,6 +843,7 @@ public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDequ * @param o element to be removed from this deque, if present * @return {@code true} if this deque changed as a result of the call */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink LinkedBlockingDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -868,6 +902,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @throws IllegalStateException if this deque is full * @see #add(Object) */ + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@Growable LinkedBlockingDeque this, Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll @@ -928,6 +963,7 @@ public boolean addAll(@Growable LinkedBlockingDeque this, Collection this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -1005,6 +1041,7 @@ public String toString() { * Atomically removes all of the elements from this deque. * The deque will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -1045,7 +1082,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this deque in proper sequence */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty LinkedBlockingDeque this) { return new Itr(); } @@ -1059,7 +1096,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this deque in reverse order */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty LinkedBlockingDeque this) { return new DescendingItr(); } @@ -1174,6 +1211,7 @@ public void forEachRemaining(Consumer action) { } while (n > 0 && p != null); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node n = lastRet; if (n == null) @@ -1361,6 +1399,7 @@ void forEachFrom(Consumer action, Node p) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1369,6 +1408,7 @@ public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingDeque this, Pred /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1377,6 +1417,7 @@ public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingDeque this, Col /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, 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 9e893c436bda..8bde84325e0a 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -50,7 +50,9 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -344,6 +346,7 @@ public int remainingCapacity() { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable LinkedBlockingQueue this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); final int c; @@ -383,6 +386,7 @@ public void put(@Growable LinkedBlockingQueue this, E e) throws InterruptedEx * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { @@ -421,6 +425,7 @@ public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, T * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedBlockingQueue this, E e) { if (e == null) throw new NullPointerException(); final AtomicInteger count = this.count; @@ -445,6 +450,7 @@ public boolean offer(@Growable LinkedBlockingQueue this, E e) { return true; } + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) throws InterruptedException { final E x; final int c; @@ -467,6 +473,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this return x; } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { final E x; final int c; @@ -492,6 +499,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this return x; } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { final AtomicInteger count = this.count; if (count.get() == 0) @@ -556,6 +564,7 @@ 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 */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink LinkedBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; fullyLock(); @@ -610,6 +619,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * * @return an array containing all of the elements in this queue */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(LinkedBlockingQueue<@PolyNull @PolySigned E> this) { fullyLock(); try { @@ -687,6 +697,7 @@ public String toString() { * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { fullyLock(); try { @@ -709,6 +720,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -719,6 +731,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -779,7 +792,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this queue in proper sequence */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedBlockingQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty LinkedBlockingQueue this) { return new Itr(); } @@ -871,6 +884,7 @@ public void forEachRemaining(Consumer action) { } while (n > 0 && p != null); } + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node p = lastRet; if (p == null) @@ -1044,6 +1058,7 @@ void forEachFrom(Consumer action, Node p) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1052,6 +1067,7 @@ public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingQueue this, Pred /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1060,6 +1076,7 @@ public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingQueue this, Col /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 155309aa74a8..9304865e8a33 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -42,7 +42,6 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -52,8 +51,11 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.AnnotatedFor; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -832,6 +834,7 @@ else if (a != null && size <= a.length) { * * @return an array containing all of the elements in this queue */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(LinkedTransferQueue<@PolyNull @PolySigned E> this) { return toArrayInternal(null); } @@ -947,6 +950,7 @@ public void forEachRemaining(Consumer action) { lastRet = q; } + @DoesNotUnrefineReceiver("modifiability") public final void remove() { final Node lastRet = this.lastRet; if (lastRet == null) @@ -1208,6 +1212,7 @@ else if (s == n) // stale * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); } @@ -1221,6 +1226,7 @@ public void put(@Growable LinkedTransferQueue this, E e) { * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedTransferQueue this, E e, long timeout, TimeUnit unit) { xfer(e, true, ASYNC, 0L); return true; @@ -1233,6 +1239,7 @@ public boolean offer(@Growable LinkedTransferQueue this, E e, long timeout, T * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); return true; @@ -1247,6 +1254,7 @@ public boolean offer(@Growable LinkedTransferQueue this, E e) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); return true; @@ -1262,6 +1270,7 @@ public boolean add(@Growable LinkedTransferQueue this, E e) { * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { return xfer(e, true, NOW, 0L) == null; } @@ -1277,6 +1286,7 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { if (xfer(e, true, SYNC, 0L) != null) { Thread.interrupted(); // failure possible only due to interrupt @@ -1298,6 +1308,7 @@ public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue * * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null) @@ -1307,6 +1318,7 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu throw new InterruptedException(); } + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { E e = xfer(null, false, SYNC, 0L); if (e != null) @@ -1315,6 +1327,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this throw new InterruptedException(); } + @DoesNotUnrefineReceiver("modifiability") public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = xfer(null, false, TIMED, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) @@ -1322,6 +1335,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this throw new InterruptedException(); } + @DoesNotUnrefineReceiver("modifiability") public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { return xfer(null, false, NOW, 0L); } @@ -1330,6 +1344,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) @@ -1344,6 +1359,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -1363,7 +1379,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue * * @return an iterator over the elements in this queue in proper sequence */ - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty LinkedTransferQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty LinkedTransferQueue this) { return new Itr(); } @@ -1447,6 +1463,7 @@ public int getWaitingConsumerCount() { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink LinkedTransferQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; restartFromHead: for (;;) { @@ -1567,6 +1584,7 @@ private void readObject(java.io.ObjectInputStream s) /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink LinkedTransferQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1575,6 +1593,7 @@ public boolean removeIf(@Shrinkable @CanShrink LinkedTransferQueue this, Pred /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1583,11 +1602,13 @@ public boolean removeAll(@Shrinkable @CanShrink LinkedTransferQueue this, Col /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { bulkRemove(e -> true); } 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 e222ab85608a..d5a76c5bec0b 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -51,7 +51,9 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -467,6 +469,7 @@ private void heapify() { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@Growable PriorityBlockingQueue this, E e) { return offer(e); } @@ -482,6 +485,7 @@ public boolean add(@Growable PriorityBlockingQueue this, E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable PriorityBlockingQueue this, E e) { if (e == null) throw new NullPointerException(); @@ -515,6 +519,7 @@ public boolean offer(@Growable PriorityBlockingQueue this, E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable PriorityBlockingQueue this, E e) { offer(e); // never need to block } @@ -534,10 +539,12 @@ public void put(@Growable PriorityBlockingQueue this, E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable PriorityBlockingQueue this, E e, long timeout, TimeUnit unit) { return offer(e); // never need to block } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -548,6 +555,7 @@ public boolean offer(@Growable PriorityBlockingQueue this, E e, long timeout, } } + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -561,6 +569,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue th return result; } + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -595,6 +604,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue th * or {@code null} if this queue uses the natural * ordering of its elements */ + @Pure public Comparator comparator() { return comparator; } @@ -666,6 +676,7 @@ 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 */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink PriorityBlockingQueue this, @Nullable @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; lock.lock(); @@ -731,6 +742,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -741,6 +753,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue< * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -765,6 +778,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue< * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -791,6 +805,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -863,7 +878,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty PriorityBlockingQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty PriorityBlockingQueue this) { return new Itr(toArray()); } @@ -892,6 +907,7 @@ public E next(@NonEmpty Itr this) { return (E)array[lastRet = cursor++]; } + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -1037,6 +1053,7 @@ public Spliterator spliterator() { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@Shrinkable @CanShrink PriorityBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1045,6 +1062,7 @@ public boolean removeIf(@Shrinkable @CanShrink PriorityBlockingQueue this, Pr /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink PriorityBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1053,6 +1071,7 @@ public boolean removeAll(@Shrinkable @CanShrink PriorityBlockingQueue this, C /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index fb83b03584e7..3950b648cf02 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -50,6 +50,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -853,6 +854,7 @@ void clean(QNode pred, QNode s) { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void put(@Growable SynchronousQueue this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); if (transferer.transfer(e, false, 0) == null) { @@ -870,6 +872,7 @@ public void put(@Growable SynchronousQueue this, E e) throws InterruptedExcep * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable SynchronousQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); @@ -889,6 +892,7 @@ public boolean offer(@Growable SynchronousQueue this, E e, long timeout, Time * {@code false} * @throws NullPointerException if the specified element is null */ + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@Growable SynchronousQueue this, E e) { if (e == null) throw new NullPointerException(); return transferer.transfer(e, true, 0) != null; @@ -901,6 +905,7 @@ public boolean offer(@Growable SynchronousQueue this, E e) { * @return the head of this queue * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { E e = transferer.transfer(null, false, 0); if (e != null) @@ -918,6 +923,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) t * specified waiting time elapses before an element is present * @throws InterruptedException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = transferer.transfer(null, true, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) @@ -932,6 +938,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, l * @return the head of this queue, or {@code null} if no * element is available */ + @DoesNotUnrefineReceiver("modifiability") public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { return transferer.transfer(null, true, 0); } @@ -973,6 +980,7 @@ public int remainingCapacity() { * Does nothing. * A {@code SynchronousQueue} has no internal capacity. */ + @DoesNotUnrefineReceiver("modifiability") public void clear(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { } @@ -996,6 +1004,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @param o the element to remove * @return {@code false} */ + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Shrinkable @CanShrink SynchronousQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return false; } @@ -1019,6 +1028,7 @@ public boolean containsAll(Collection c) { * @param c the collection * @return {@code false} */ + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@Shrinkable @CanShrink SynchronousQueue this, Collection c) { return false; } @@ -1030,6 +1040,7 @@ public boolean removeAll(@Shrinkable @CanShrink SynchronousQueue this, Collec * @param c the collection * @return {@code false} */ + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, Collection c) { return false; } @@ -1053,7 +1064,7 @@ public E peek() { * @return an empty iterator */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty SynchronousQueue this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty SynchronousQueue this) { return Collections.emptyIterator(); } @@ -1086,7 +1097,6 @@ public Spliterator spliterator() { * @return the specified array * @throws NullPointerException if the specified array is null */ - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length > 0) a[0] = null; @@ -1107,6 +1117,7 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) @@ -1123,6 +1134,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue th * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) diff --git a/src/java.base/share/classes/java/util/stream/DoublePipeline.java b/src/java.base/share/classes/java/util/stream/DoublePipeline.java index 9771440f8aa9..bb4c3d8a8962 100644 --- a/src/java.base/share/classes/java/util/stream/DoublePipeline.java +++ b/src/java.base/share/classes/java/util/stream/DoublePipeline.java @@ -567,6 +567,7 @@ public final OptionalDouble findAny() { } @Override + @SideEffectFree public final double[] toArray() { return Nodes.flattenDouble((Node.OfDouble) evaluateToArrayNode(Double[]::new)) .asPrimitiveArray(); diff --git a/src/java.base/share/classes/java/util/stream/IntPipeline.java b/src/java.base/share/classes/java/util/stream/IntPipeline.java index f0d019c7d74a..6b3b31d80846 100644 --- a/src/java.base/share/classes/java/util/stream/IntPipeline.java +++ b/src/java.base/share/classes/java/util/stream/IntPipeline.java @@ -558,6 +558,7 @@ public final OptionalInt findAny() { } @Override + @SideEffectFree public final int[] toArray() { return Nodes.flattenInt((Node.OfInt) evaluateToArrayNode(Integer[]::new)) .asPrimitiveArray(); diff --git a/src/java.base/share/classes/java/util/stream/LongPipeline.java b/src/java.base/share/classes/java/util/stream/LongPipeline.java index 227a071100af..ebf3e6a0acaf 100644 --- a/src/java.base/share/classes/java/util/stream/LongPipeline.java +++ b/src/java.base/share/classes/java/util/stream/LongPipeline.java @@ -541,6 +541,7 @@ public final OptionalLong findAny() { } @Override + @SideEffectFree public final long[] toArray() { return Nodes.flattenLong((Node.OfLong) evaluateToArrayNode(Long[]::new)) .asPrimitiveArray(); diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java index 7193a7d7e86e..4e592f283465 100644 --- a/src/java.base/share/classes/java/util/stream/Stream.java +++ b/src/java.base/share/classes/java/util/stream/Stream.java @@ -922,7 +922,6 @@ default Stream dropWhile(Predicate predicate) { * stream is not assignable to the {@linkplain Class#getComponentType * runtime component type} of the generated array */ - @SideEffectFree A[] toArray(IntFunction generator); /** diff --git a/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java b/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java index c4601ef3e6cc..b07f752908c9 100644 --- a/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java +++ b/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java @@ -62,18 +62,22 @@ public int add(final String string) { throw new InternalError("Can not add strings at runtime"); } + @Pure public static int hashCode(String s) { return hashCode(s, HASH_MULTIPLIER); } + @Pure public static int hashCode(String s, int seed) { return unmaskedHashCode(s, seed) & POSITIVE_MASK; } + @Pure public static int hashCode(String module, String name) { return hashCode(module, name, HASH_MULTIPLIER); } + @Pure public static int hashCode(String module, String name, int seed) { seed = (seed * HASH_MULTIPLIER) ^ ('/'); seed = unmaskedHashCode(module, seed); diff --git a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java index 61be28519fc2..daeb71a58cea 100644 --- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java @@ -219,6 +219,7 @@ private static int signedHashCode(int result, byte[] a, int fromIndex, int lengt return result; } + @Pure private static int hashCode(int result, byte[] a, int fromIndex, int length) { int end = fromIndex + length; for (int i = fromIndex; i < end; i++) { @@ -227,6 +228,7 @@ private static int hashCode(int result, byte[] a, int fromIndex, int length) { return result; } + @Pure private static int hashCode(int result, char[] a, int fromIndex, int length) { int end = fromIndex + length; for (int i = fromIndex; i < end; i++) { @@ -235,6 +237,7 @@ private static int hashCode(int result, char[] a, int fromIndex, int length) { return result; } + @Pure private static int hashCode(int result, short[] a, int fromIndex, int length) { int end = fromIndex + length; for (int i = fromIndex; i < end; i++) { @@ -243,6 +246,7 @@ private static int hashCode(int result, short[] a, int fromIndex, int length) { return result; } + @Pure private static int hashCode(int result, int[] a, int fromIndex, int length) { int end = fromIndex + length; for (int i = fromIndex; i < end; i++) { diff --git a/src/java.desktop/share/classes/javax/swing/DefaultListModel.java b/src/java.desktop/share/classes/javax/swing/DefaultListModel.java index 9d519927b677..d75de937e94b 100644 --- a/src/java.desktop/share/classes/javax/swing/DefaultListModel.java +++ b/src/java.desktop/share/classes/javax/swing/DefaultListModel.java @@ -268,6 +268,7 @@ public int lastIndexOf(Object elem, int index) { * @see #get(int) * @see Vector#elementAt(int) */ + @SideEffectFree public E elementAt(int index) { return delegate.elementAt(index); } diff --git a/test/jdk/java/util/SequencedCollection/SimpleDeque.java b/test/jdk/java/util/SequencedCollection/SimpleDeque.java index c1ed07210fba..3524ba2c075f 100644 --- a/test/jdk/java/util/SequencedCollection/SimpleDeque.java +++ b/test/jdk/java/util/SequencedCollection/SimpleDeque.java @@ -178,6 +178,7 @@ public E poll() { return deque.poll(); } + @SideEffectFree public E element() { return deque.element(); } From ec30b3eada71c97fd15fb3392d04c15cc6580121 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 11 Apr 2026 12:19:01 -0700 Subject: [PATCH 044/119] Update qualifiers --- README.md | 11 +++---- checker-qual.jar | Bin 275625 -> 286009 bytes src/java.base/share/classes/module-info.java | 3 +- .../checker/fenum/qual/FenumUnqualified.java | 3 +- .../checker/formatter/qual/Format.java | 2 +- .../checker/index/qual/EnsuresLTLengthOf.java | 2 +- .../checker/index/qual/IndexFor.java | 2 +- .../checker/index/qual/IndexOrHigh.java | 4 +-- .../checker/index/qual/IndexOrLow.java | 6 ++-- .../checker/lock/qual/LockHeld.java | 3 +- .../checker/lock/qual/LockPossiblyHeld.java | 3 +- .../checker/modifiability/qual/Growable.java | 22 +++++++++++++ .../modifiability/qual/Modifiable.java | 22 +++++++++++++ .../checker/modifiability/qual/PolyGrow.java | 23 +++++++++++++ .../modifiability/qual/PolyModifiable.java | 31 ++++++++++++++++++ .../modifiability/qual/PolyReplace.java | 23 +++++++++++++ .../modifiability/qual/PolyShrink.java | 22 +++++++++++++ .../modifiability/qual/Replaceable.java | 22 +++++++++++++ .../modifiability/qual/Shrinkable.java | 22 +++++++++++++ .../checker/modifiability/qual/ThrowsUOE.java | 18 ++++++++++ .../modifiability/qual/UnknownGrow.java | 24 ++++++++++++++ .../qual/UnknownModifiability.java | 23 +++++++++++++ .../modifiability/qual/UnknownReplace.java | 25 ++++++++++++++ .../modifiability/qual/UnknownShrink.java | 25 ++++++++++++++ .../modifiability/qual/Unmodifiable.java | 22 +++++++++++++ .../checker/mustcall/qual/MustCallAlias.java | 2 -- .../nonempty/qual/EnsuresNonEmpty.java | 14 ++++---- .../nullness/qual/AssertNonNullIfNonNull.java | 10 +++--- .../nullness/qual/EnsuresNonNullIf.java | 2 +- .../checker/optional/qual/EnsuresPresent.java | 14 ++++---- .../checker/regex/qual/PartialRegex.java | 2 +- .../checker/regex/qual/RegexBottom.java | 2 +- .../signature/qual/SignatureUnknown.java | 3 +- .../checker/signedness/qual/Signed.java | 11 ++----- .../checker/signedness/qual/Unsigned.java | 4 +-- .../checker/units/qual/PolyUnit.java | 14 ++++---- .../common/aliasing/qual/MaybeLeaked.java | 3 +- .../common/subtyping/qual/Unqualified.java | 3 +- .../common/value/qual/DoesNotMatchRegex.java | 2 +- .../qual/IntRangeFromGTENegativeOne.java | 2 +- .../value/qual/IntRangeFromNonNegative.java | 2 +- .../value/qual/IntRangeFromPositive.java | 8 ++--- .../common/value/qual/MatchesRegex.java | 2 +- .../qual/DoesNotUnrefineReceiver.java | 31 ++++++++++++++++++ .../dataflow/qual/SideEffectsOnly.java | 29 ---------------- .../framework/qual/CFComment.java | 4 +-- .../framework/qual/EnsuresQualifierIf.java | 8 ++--- .../qual/PostconditionAnnotation.java | 6 ++-- .../qual/PreconditionAnnotation.java | 20 +++++------ 49 files changed, 442 insertions(+), 119 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java create mode 100644 src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java delete mode 100644 src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java diff --git a/README.md b/README.md index f113339385cd..383fb269c884 100644 --- a/README.md +++ b/README.md @@ -133,13 +133,12 @@ cp -p $CHECKERFRAMEWORK/checker-qual/build/libs/checker-qual-*-sources.jar check jar tf checker-qual.jar | grep '\.java$' | sed 's/\/[^/]*\.java/;/' | sed 's/\//./g' | sed 's/^/ exports /' | sort -u ``` -The result of the command will be a list of export lines. -Replace the existing export lines present in -`src/java.base/share/classes/module-info.java` with the newly-generated list of -exports. If no new packages were added, then likely no changes are needed -in the `module-info.java` file. +It addition to updating `.java` files, the command will output a list of export +lines. Place them in `src/java.base/share/classes/module-info.java`. If no new +packages were recently added to the Checker Framework, then likely no changes +are needed in the `module-info.java` file. -Commit the changes, including the new `checker.jar` file and any new `.java` +Commit the changes, including the new `checker-qual.jar` file and any new `.java` files in a `qual/` directory. (Both are used, by different parts of the build.) ## The typetools/jdk21u repository diff --git a/checker-qual.jar b/checker-qual.jar index a3039199c5b6c49c06ef953b98eaffa620871571..8c13f44b86d88603313b832898f97b0f711bba7d 100644 GIT binary patch delta 39189 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 delta 30071 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 Nk%i@G8hj08`5y~W&~g9( diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 5a4f09b96283..17659d96aa63 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -82,12 +82,13 @@ exports org.checkerframework.checker.fenum.qual; exports org.checkerframework.checker.formatter.qual; exports org.checkerframework.checker.guieffect.qual; - exports org.checkerframework.checker.i18nformatter.qual; exports org.checkerframework.checker.i18n.qual; + exports org.checkerframework.checker.i18nformatter.qual; exports org.checkerframework.checker.index.qual; exports org.checkerframework.checker.initialization.qual; exports org.checkerframework.checker.interning.qual; exports org.checkerframework.checker.lock.qual; + exports org.checkerframework.checker.modifiability.qual; exports org.checkerframework.checker.mustcall.qual; exports org.checkerframework.checker.nonempty.qual; exports org.checkerframework.checker.nullness.qual; diff --git a/src/java.base/share/classes/org/checkerframework/checker/fenum/qual/FenumUnqualified.java b/src/java.base/share/classes/org/checkerframework/checker/fenum/qual/FenumUnqualified.java index 4eeaf9692145..d2450144d9fd 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/fenum/qual/FenumUnqualified.java +++ b/src/java.base/share/classes/org/checkerframework/checker/fenum/qual/FenumUnqualified.java @@ -1,6 +1,7 @@ package org.checkerframework.checker.fenum.qual; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -20,7 +21,7 @@ */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target({}) // empty target prevents programmers from writing this in a program +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({FenumTop.class}) @DefaultQualifierInHierarchy @DefaultFor(TypeUseLocation.EXCEPTION_PARAMETER) diff --git a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/Format.java b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/Format.java index 878fce1ee227..a5249f25b0c4 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/Format.java +++ b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/Format.java @@ -19,7 +19,7 @@ *
  * {@literal @}Format({GENERAL, INT}) String f = "String '%s' has length %d";
  *
- *  String.format(f, "Example", 7);
+ * String.format(f, "Example", 7);
  * 
* * diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/EnsuresLTLengthOf.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/EnsuresLTLengthOf.java index 6903a5e9f933..3c8474f49b8d 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/EnsuresLTLengthOf.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/EnsuresLTLengthOf.java @@ -36,7 +36,7 @@ * *
{@code
  * public void useShiftIndex(@NonNegative int x) {
- *    // :: error: (argument)
+ *    // :: error: [argument]
  *    Arrays.fill(array, end, end + x, null);
  *    shiftIndex(x);
  *    Arrays.fill(array, end, end + x, null);
diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexFor.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexFor.java
index 7a8ba2733138..6bf2a80529c4 100644
--- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexFor.java
+++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexFor.java
@@ -14,7 +14,7 @@
  * different lengths.
  *
  * 

The + * href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/String.html#charAt(int)"> * {@code String.charAt(int)} method is declared as * *

{@code
diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java
index c1f20a6dc816..d24df9bc7748 100644
--- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java
+++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java
@@ -11,7 +11,7 @@
  * sequence's length.
  *
  * 

The + * href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Arrays.html#binarySearch(java.lang.Object%5B%5D,int,int,java.lang.Object)"> * {@code Arrays.binarySearch} method is declared as * *

{@code
@@ -33,6 +33,6 @@
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 public @interface IndexOrHigh {
-  /** Sequences that the annotated expression is a valid index for or is equal to the lengeth of. */
+  /** Sequences that the annotated expression is a valid index for or is equal to the length of. */
   String[] value();
 }
diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrLow.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrLow.java
index 04a956d9b5ab..aee1643956a6 100644
--- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrLow.java
+++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrLow.java
@@ -10,13 +10,13 @@
  * An integer that is either -1 or is a valid index for each of the given sequences.
  *
  * 

The + * href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/String.html#indexOf(java.lang.String)"> * {@code String.indexOf(String)} method is declared as * *


- *   class String {
+ *  class String {
  *    {@literal @}IndexOrLow("this") int indexOf(String str) { ... }
- *   }
+ *  }
  * 
* *

Writing {@code @IndexOrLow("arr")} is equivalent to writing {@link diff --git a/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockHeld.java b/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockHeld.java index d77d8c0842f6..e49a60ccb08a 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockHeld.java +++ b/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockHeld.java @@ -1,6 +1,7 @@ package org.checkerframework.checker.lock.qual; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -19,7 +20,7 @@ */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target({}) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf(LockPossiblyHeld.class) // This is the bottom type in this hierarchy @InvisibleQualifier public @interface LockHeld {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java b/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java index 15cbf89c7eb8..7dc177b091b4 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java +++ b/src/java.base/share/classes/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java @@ -1,6 +1,7 @@ package org.checkerframework.checker.lock.qual; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -23,7 +24,7 @@ */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target({}) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @InvisibleQualifier @SubtypeOf({}) @DefaultQualifierInHierarchy diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java new file mode 100644 index 000000000000..5c2b1b7315c1 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling grow operations such as {@code add}, {@code addAll}, etc. on this collection will not + * result in throwing {@link UnsupportedOperationException}. + * + *

No guarantees are made about shrink or replace operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownGrow.class) +public @interface Growable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java new file mode 100644 index 000000000000..97d492135de4 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Convenience alias meaning {@code @Growable @Shrinkable @Replaceable}. Calling grow, shrink, and + * replace operations such as {@code add}, {@code remove}, {@code set}, etc. on this collection will + * not result in throwing {@link UnsupportedOperationException}. + * + *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to + * {@code @Growable @Shrinkable @Replaceable} on each annotated type. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +public @interface Modifiable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java new file mode 100644 index 000000000000..3a4d5b43fbf8 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Grow hierarchy. + * + *

When used on a method, the Grow capability of the return type matches the Grow capability of + * the argument or receiver annotated with {@code @PolyGrow}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(UnknownGrow.class) +public @interface PolyGrow {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java new file mode 100644 index 000000000000..73bc67261eb3 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -0,0 +1,31 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * Convenience alias meaning {@code @PolyGrow @PolyShrink @PolyReplace}. A polymorphic qualifier for + * all three modifiability hierarchies. + * + *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to + * {@code @PolyGrow @PolyShrink @PolyReplace} on each annotated type. + * + *

Use on methods that preserve or transfer modifiability — for example, {@code + * List.subList()}, {@code iterator()}, or {@code stream()}. + * + *

For example: + * + *


+ * class Example {
+ *   @PolyModifiable List<E> subList(@PolyModifiable List<E> this, int from, int to);
+ * }
+ * 
+ * + * If the receiver is {@code @Unmodifiable}, the return is {@code @Unmodifiable}. If the receiver is + * {@code @Modifiable}, the return is {@code @Modifiable}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +public @interface PolyModifiable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java new file mode 100644 index 000000000000..eb6e7ac5af7d --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Replace hierarchy. + * + *

When used on a method, the Replace capability of the return type matches the Replace + * capability of the argument or receiver annotated with {@code @PolyReplace}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(UnknownReplace.class) +public @interface PolyReplace {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java new file mode 100644 index 000000000000..b491d8626f99 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Shrink hierarchy that preserves the shrink capability. + * + *

Use on methods that preserve shrinkability — for example, {@code Map.keySet()}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(UnknownShrink.class) +public @interface PolyShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java new file mode 100644 index 000000000000..bc6199b61f62 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling replace operations such as {@code set}, {@code replaceAll}, etc. on this collection will + * not result in throwing {@link UnsupportedOperationException}. + * + *

No guarantees are made about grow or shrink operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownReplace.class) +public @interface Replaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java new file mode 100644 index 000000000000..cabe5a275869 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling shrink operations such as {@code remove}, {@code clear}, etc. on this collection will not + * result in throwing {@link UnsupportedOperationException}. + * + *

No guarantees are made about grow or replace operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownShrink.class) +public @interface Shrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java new file mode 100644 index 000000000000..3651620510c7 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java @@ -0,0 +1,18 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated method always throws {@link UnsupportedOperationException} when + * called. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +public @interface ThrowsUOE {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java new file mode 100644 index 000000000000..30f3c460deec --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java @@ -0,0 +1,24 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The top qualifier in the Grow hierarchy. Represents an unknown or absent grow capability. The + * checker cannot determine whether the collection supports grow operations such as {@code add}. + * + *

This is the default qualifier for unannotated types in the Grow hierarchy. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({}) +@DefaultQualifierInHierarchy +public @interface UnknownGrow {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java new file mode 100644 index 000000000000..f653f09d2d03 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Convenience alias meaning {@code @UnknownGrow @UnknownShrink @UnknownReplace}. Represents an + * unknown or arbitrary modifiability capability; the checker cannot determine whether the + * collection is growable, shrinkable, or replaceable. + * + *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to + * {@code @UnknownGrow @UnknownShrink @UnknownReplace} on each annotated type. It is equivalent to + * {@link Unmodifiable}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +public @interface UnknownModifiability {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java new file mode 100644 index 000000000000..a793d64f521f --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The top qualifier in the Replace hierarchy. Represents an unknown or absent replace capability. + * The checker cannot determine whether the collection supports replace operations such as {@code + * set} or {@code replaceAll}. + * + *

This is the default qualifier for unannotated types in the Replace hierarchy. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({}) +@DefaultQualifierInHierarchy +public @interface UnknownReplace {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java new file mode 100644 index 000000000000..7f87345b521c --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The top qualifier in the Shrink hierarchy. Represents an unknown or absent shrink capability. The + * checker cannot determine whether the collection supports shrink operations such as {@code remove} + * or {@code clear}. + * + *

This is the default qualifier for unannotated types in the Shrink hierarchy. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({}) +@DefaultQualifierInHierarchy +public @interface UnknownShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java new file mode 100644 index 000000000000..f5252ff71572 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Convenience alias meaning {@code @UnknownGrow @UnknownShrink @UnknownReplace}. Calling any + * mutating operation on this collection (growing, shrinking, or replacing) will throw {@link + * UnsupportedOperationException}. + * + *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to + * {@code @UnknownGrow @UnknownShrink @UnknownReplace} on each annotated type. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +public @interface Unmodifiable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/mustcall/qual/MustCallAlias.java b/src/java.base/share/classes/org/checkerframework/checker/mustcall/qual/MustCallAlias.java index 731ad6597017..f99eee8d4391 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/mustcall/qual/MustCallAlias.java +++ b/src/java.base/share/classes/org/checkerframework/checker/mustcall/qual/MustCallAlias.java @@ -78,7 +78,5 @@ */ @Documented @Retention(RetentionPolicy.RUNTIME) -// In Java 11, this can be: -// @Target({ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.METHOD}) @Target({ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE_USE}) public @interface MustCallAlias {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmpty.java b/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmpty.java index 0b0b0ba748ce..520584f6269f 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmpty.java +++ b/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmpty.java @@ -18,19 +18,19 @@ * effect: * *


- *   {@literal @}EnsuresNonEmpty("ids")
- *   void addId(String id) {
- *     ids.add(id);
- *   }
+ *  {@literal @}EnsuresNonEmpty("ids")
+ *  void addId(String id) {
+ *    ids.add(id);
+ *  }
  * 
* * It can also be used for a method that fails if a given value is empty, indicating that the * argument is non-empty if the method returns normally: * *

- *   /** Throws an exception if the argument is empty. */
- *   {@literal @}EnsuresNonEmpty("#1")
- *   void useTheMap(Map<T, U> arg) { ... }
+ *  /** Throws an exception if the argument is empty. */
+ *  {@literal @}EnsuresNonEmpty("#1")
+ *  void useTheMap(Map<T, U> arg) { ... }
  * 
* * @see NonEmpty diff --git a/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/AssertNonNullIfNonNull.java b/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/AssertNonNullIfNonNull.java index 68408f19bc0c..18fb2a854609 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/AssertNonNullIfNonNull.java +++ b/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/AssertNonNullIfNonNull.java @@ -15,11 +15,11 @@ *

Here is an example use: * *


- *    {@literal @}AssertNonNullIfNonNull("id")
- *    {@literal @}Pure
- *     public @Nullable Long getId() {
- *         return id;
- *     }
+ *  {@literal @}AssertNonNullIfNonNull("id")
+ *  {@literal @}Pure
+ *  public @Nullable Long getId() {
+ *    return id;
+ *  }
  * 
* * Note the direction of the implication. This annotation says that if the result is non-null, then diff --git a/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/EnsuresNonNullIf.java b/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/EnsuresNonNullIf.java index d74189c154ce..5d0fcf215b95 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/EnsuresNonNullIf.java +++ b/src/java.base/share/classes/org/checkerframework/checker/nullness/qual/EnsuresNonNullIf.java @@ -84,7 +84,7 @@ /** * Returns Java expression(s) that are non-null after the method returns the given result. * - * @return Java expression(s) that are non-null after the method returns the given result + * @return the Java expression(s) that are non-null after the method returns the given result * @checker_framework.manual #java-expressions-as-arguments Syntax of Java expressions */ String[] expression(); diff --git a/src/java.base/share/classes/org/checkerframework/checker/optional/qual/EnsuresPresent.java b/src/java.base/share/classes/org/checkerframework/checker/optional/qual/EnsuresPresent.java index 8539b7aca7cc..c3c16a099fbe 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/optional/qual/EnsuresPresent.java +++ b/src/java.base/share/classes/org/checkerframework/checker/optional/qual/EnsuresPresent.java @@ -15,19 +15,19 @@ *

This postcondition annotation is useful for methods that construct a present Optional: * *


- *   {@literal @}EnsuresPresent("optStr")
- *   void initialize() {
- *     optStr = Optional.of("abc");
- *   }
+ *  {@literal @}EnsuresPresent("optStr")
+ *  void initialize() {
+ *    optStr = Optional.of("abc");
+ *  }
  * 
* * It can also be used for a method that fails if a given Optional value is empty, indicating that * the argument is present if the method returns normally: * *

- *   /** Throws an exception if the argument is empty. */
- *   {@literal @}EnsuresPresent("#1")
- *   void useTheOptional(Optional<T> arg) { ... }
+ *  /** Throws an exception if the argument is empty. */
+ *  {@literal @}EnsuresPresent("#1")
+ *  void useTheOptional(Optional<T> arg) { ... }
  * 
* * @see Present diff --git a/src/java.base/share/classes/org/checkerframework/checker/regex/qual/PartialRegex.java b/src/java.base/share/classes/org/checkerframework/checker/regex/qual/PartialRegex.java index 2519b6749a9d..c4402a2c12f8 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/regex/qual/PartialRegex.java +++ b/src/java.base/share/classes/org/checkerframework/checker/regex/qual/PartialRegex.java @@ -21,7 +21,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({}) // empty target prevents programmers from writing this in a program @InvisibleQualifier -@SubtypeOf(org.checkerframework.checker.regex.qual.UnknownRegex.class) +@SubtypeOf(UnknownRegex.class) public @interface PartialRegex { /** diff --git a/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java b/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java index e0f226b752ad..2ffcb62ad718 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java +++ b/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java @@ -22,6 +22,6 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @InvisibleQualifier -@SubtypeOf({Regex.class, org.checkerframework.checker.regex.qual.PartialRegex.class}) +@SubtypeOf({Regex.class, PartialRegex.class}) @DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) public @interface RegexBottom {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/SignatureUnknown.java b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/SignatureUnknown.java index a96229fd6573..515085e1b2f8 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/SignatureUnknown.java +++ b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/SignatureUnknown.java @@ -1,6 +1,7 @@ package org.checkerframework.checker.signature.qual; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -17,7 +18,7 @@ */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target({}) // empty target prevents programmers from writing this in a program +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy public @interface SignatureUnknown {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Signed.java b/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Signed.java index 797f4e91339b..8a587363fd98 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Signed.java +++ b/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Signed.java @@ -32,16 +32,9 @@ TypeKind.FLOAT, TypeKind.DOUBLE }, - types = { - java.lang.Byte.class, - java.lang.Integer.class, - java.lang.Long.class, - java.lang.Short.class, - java.lang.Float.class, - java.lang.Double.class - }, + types = {Byte.class, Integer.class, Long.class, Short.class, Float.class, Double.class}, value = TypeUseLocation.EXCEPTION_PARAMETER) @UpperBoundFor( typeKinds = {TypeKind.FLOAT, TypeKind.DOUBLE}, - types = {java.lang.Float.class, java.lang.Double.class}) + types = {Float.class, Double.class}) public @interface Signed {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Unsigned.java b/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Unsigned.java index 534c5acf00b9..e75a8879a4c9 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Unsigned.java +++ b/src/java.base/share/classes/org/checkerframework/checker/signedness/qual/Unsigned.java @@ -23,8 +23,8 @@ @SubtypeOf({UnknownSignedness.class}) @DefaultFor( typeKinds = {TypeKind.CHAR}, - types = {java.lang.Character.class}) + types = {Character.class}) @UpperBoundFor( typeKinds = {TypeKind.CHAR}, - types = {java.lang.Character.class}) + types = {Character.class}) public @interface Unsigned {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/units/qual/PolyUnit.java b/src/java.base/share/classes/org/checkerframework/checker/units/qual/PolyUnit.java index 0435cb42df4e..bc7a669f824b 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/units/qual/PolyUnit.java +++ b/src/java.base/share/classes/org/checkerframework/checker/units/qual/PolyUnit.java @@ -18,19 +18,19 @@ * meters or seconds: * *

- * {@literal @}PolyUnit int triplePolyUnit(@PolyUnit int amount) {
+ *  {@literal @}PolyUnit int triplePolyUnit(@PolyUnit int amount) {
  *    return 3*amount;
  *  }
  *
  *  void testPolyUnit() {
- *   {@literal @}m int m1 = 7 * UnitsTools.m;
- *   {@literal @}m int m2 = triplePolyUnit(m1);
+ *    {@literal @}m int m1 = 7 * UnitsTools.m;
+ *    {@literal @}m int m2 = triplePolyUnit(m1);
  *
- *   {@literal @}s int sec1 = 7 * UnitsTools.s;
- *   {@literal @}s int sec2 = triplePolyUnit(sec1);
+ *    {@literal @}s int sec1 = 7 * UnitsTools.s;
+ *    {@literal @}s int sec2 = triplePolyUnit(sec1);
  *
- *    // :: error: (assignment)
- *   {@literal @}s int sec3 = triplePolyUnit(m1);
+ *    // :: error: [assignment]
+ *    {@literal @}s int sec3 = triplePolyUnit(m1);
  *  }
  * 
* diff --git a/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/MaybeLeaked.java b/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/MaybeLeaked.java index 9038b6b75b01..2afe7ee638eb 100644 --- a/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/MaybeLeaked.java +++ b/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/MaybeLeaked.java @@ -1,6 +1,7 @@ package org.checkerframework.common.aliasing.qual; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -21,7 +22,7 @@ */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target({}) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @DefaultQualifierInHierarchy @SubtypeOf({LeakedToResult.class}) @InvisibleQualifier diff --git a/src/java.base/share/classes/org/checkerframework/common/subtyping/qual/Unqualified.java b/src/java.base/share/classes/org/checkerframework/common/subtyping/qual/Unqualified.java index df08edb7b9b6..3e9b8ab1fcc2 100644 --- a/src/java.base/share/classes/org/checkerframework/common/subtyping/qual/Unqualified.java +++ b/src/java.base/share/classes/org/checkerframework/common/subtyping/qual/Unqualified.java @@ -1,6 +1,7 @@ package org.checkerframework.common.subtyping.qual; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -21,7 +22,7 @@ */ @Documented @Retention(RetentionPolicy.SOURCE) // don't store in class file -@Target({}) // empty target prevents programmers from writing this in a program. +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @InvisibleQualifier @SubtypeOf({}) public @interface Unqualified {} diff --git a/src/java.base/share/classes/org/checkerframework/common/value/qual/DoesNotMatchRegex.java b/src/java.base/share/classes/org/checkerframework/common/value/qual/DoesNotMatchRegex.java index 8fde439d8e77..e28e35b4d038 100644 --- a/src/java.base/share/classes/org/checkerframework/common/value/qual/DoesNotMatchRegex.java +++ b/src/java.base/share/classes/org/checkerframework/common/value/qual/DoesNotMatchRegex.java @@ -12,7 +12,7 @@ * Java regular expressions. If an expression's type has this annotation, then at run time, the * expression evaluates to a string that matches none of the regular expressions. Matching is via * the java.lang.String#matches + * href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/String.html#matches(java.lang.String)">java.lang.String#matches * method, which matches against the entire string (it does not look for a match against a * substring). * diff --git a/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromGTENegativeOne.java b/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromGTENegativeOne.java index fc65c4a9f203..a789b43c8a30 100644 --- a/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromGTENegativeOne.java +++ b/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromGTENegativeOne.java @@ -14,7 +14,7 @@ * *

IntRangeFromGTENegativeOne annotations derived from GTENegativeOne annotations are used to * create IntRange annotations, but IntRangeFromGTENegativeOne annotations are not checked when they - * appear on the left hand side of expressions. Therefore, the Index Checker MUST be run on any code + * appear on the left-hand side of expressions. Therefore, the Index Checker MUST be run on any code * with @GTENegativeOne annotations on the left-hand side of expressions, since the Value Checker * will derive information from them but not check them. * diff --git a/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromNonNegative.java b/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromNonNegative.java index 434ff259de39..23f834b5ac67 100644 --- a/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromNonNegative.java +++ b/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromNonNegative.java @@ -14,7 +14,7 @@ * *

IntRangeFromNonNegative annotations derived from NonNegative annotations are used to create * IntRange annotations, but IntRangeFromNonNegative annotations are not checked when they appear on - * the left hand side of expressions. Therefore, the Index Checker MUST be run on any code + * the left-hand side of expressions. Therefore, the Index Checker MUST be run on any code * with @NonNegative annotations on the left-hand side of expressions, since the Value Checker will * derive information from them but not check them. * diff --git a/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromPositive.java b/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromPositive.java index 4941505975a3..47f6517a9786 100644 --- a/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromPositive.java +++ b/src/java.base/share/classes/org/checkerframework/common/value/qual/IntRangeFromPositive.java @@ -13,10 +13,10 @@ * annotation. * *

IntRangeFromPositive annotations derived from Positive annotations are used to create IntRange - * annotations, but IntRangeFromPositive annotations are not checked when they appear on the left - * hand side of expressions. Therefore, the Index Checker MUST be run on any code with @Positive - * annotations on the left-hand side of expressions, since the Value Checker will derive information - * from them but not check them. + * annotations, but IntRangeFromPositive annotations are not checked when they appear on the + * left-hand side of expressions. Therefore, the Index Checker MUST be run on any code + * with @Positive annotations on the left-hand side of expressions, since the Value Checker will + * derive information from them but not check them. * *

It is an error to write this annotation directly. {@code @Positive} or {@code IntRange(from = * 1, to = Integer.MAX_VALUE)} should always be written instead. This annotation is not retained in diff --git a/src/java.base/share/classes/org/checkerframework/common/value/qual/MatchesRegex.java b/src/java.base/share/classes/org/checkerframework/common/value/qual/MatchesRegex.java index 5c10b127c353..2813aba32b92 100644 --- a/src/java.base/share/classes/org/checkerframework/common/value/qual/MatchesRegex.java +++ b/src/java.base/share/classes/org/checkerframework/common/value/qual/MatchesRegex.java @@ -12,7 +12,7 @@ * Java regular expressions. If an expression's type has this annotation, then at run time, the * expression evaluates to a string that matches at least one of the regular expressions. Matching * is via the java.lang.String#matches + * href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/String.html#matches(java.lang.String)">java.lang.String#matches * method, which matches against the entire string (it does not look for a match against a * substring). * diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java b/src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java new file mode 100644 index 000000000000..329ea505d64e --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java @@ -0,0 +1,31 @@ +package org.checkerframework.dataflow.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * At a call to a side-effecting method, the framework ordinarily discards all refined type + * information, since the side-effecting method might invalidate that information. This annotation + * indicates that, at a call to the annotated method, the receiver's type should not be unrefined. + * That is, a call to the method does not affect the type qualifier (in the given hierarchy). + * + * @checker_framework.manual #type-refinement-purity Side effects, determinism, purity, and + * flow-sensitive analysis + */ +// @InheritedAnnotation cannot be written here, because "dataflow" project cannot depend on +// "framework" project. +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +public @interface DoesNotUnrefineReceiver { + /** + * The name of the checker(s) that this annotation affects. For example, "modifiability" or + * "nullness". Use "allcheckers" to affect all checkers. + * + * @return the name of the checker that this annotation affects + */ + String[] value(); +} diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java deleted file mode 100644 index ab6a7dd1718f..000000000000 --- a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.checkerframework.dataflow.qual; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.checkerframework.framework.qual.JavaExpression; - -/** - * A method annotated with the declaration annotation {@code @SideEffectsOnly("A", "B")} changes the - * value of at most the expressions A and B. All other expressions have the same value before and - * after a call to the method. - * - * @checker_framework.manual #type-refinement-purity Specifying side effects - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) -public @interface SideEffectsOnly { - /** - * An upper bound on the expressions that this method might change the value of. - * - * @return the Java expressions that the annotated method might side-effect - * @checker_framework.manual #java-expressions-as-arguments Syntax of Java expressions - */ - @JavaExpression - public String[] value(); -} diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/CFComment.java b/src/java.base/share/classes/org/checkerframework/framework/qual/CFComment.java index f9ef370b5914..f7b6fa75c2ec 100644 --- a/src/java.base/share/classes/org/checkerframework/framework/qual/CFComment.java +++ b/src/java.base/share/classes/org/checkerframework/framework/qual/CFComment.java @@ -13,9 +13,9 @@ *

Here is an example: * *


- * {@literal @}CFComment("interning: factory methods guarantee that all elements are interned")
+ *  {@literal @}CFComment("interning: factory methods guarantee that all elements are interned")
  *  public class MyClass {
- *   {@literal @}CFComment({"nullness: non-null return type is more specific than in superclass",
+ *    {@literal @}CFComment({"nullness: non-null return type is more specific than in superclass",
  *                "signedness: comment related to Signedness type system"})
  *    public String myMethod() { ... }
  * }
diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/EnsuresQualifierIf.java b/src/java.base/share/classes/org/checkerframework/framework/qual/EnsuresQualifierIf.java
index e7637ba890bf..d1f9ff997f99 100644
--- a/src/java.base/share/classes/org/checkerframework/framework/qual/EnsuresQualifierIf.java
+++ b/src/java.base/share/classes/org/checkerframework/framework/qual/EnsuresQualifierIf.java
@@ -18,10 +18,10 @@
  * 

Here is an example use: * *


- *   {@literal @}EnsuresQualifierIf(result = true, expression = "#1", qualifier = Odd.class)
- *    boolean isOdd(int p1, int p2) {
- *        return p1 % 2 == 1;
- *    }
+ *  {@literal @}EnsuresQualifierIf(result = true, expression = "#1", qualifier = Odd.class)
+ *   boolean isOdd(int p1, int p2) {
+ *     return p1 % 2 == 1;
+ *   }
  * 
* *

This annotation is only applicable to methods with a boolean return type. diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/PostconditionAnnotation.java b/src/java.base/share/classes/org/checkerframework/framework/qual/PostconditionAnnotation.java index 67bb434e8483..2017eccd81f3 100644 --- a/src/java.base/share/classes/org/checkerframework/framework/qual/PostconditionAnnotation.java +++ b/src/java.base/share/classes/org/checkerframework/framework/qual/PostconditionAnnotation.java @@ -31,8 +31,8 @@ * org.checkerframework.common.value.qual.MinLen} qualifier: * *


- * {@literal @}PostconditionAnnotation(qualifier = MinLen.class)
- * {@literal @}Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ *  {@literal @}PostconditionAnnotation(qualifier = MinLen.class)
+ *  {@literal @}Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
  *  public {@literal @}interface EnsuresMinLen {
  *    String[] value();
  *    {@literal @}QualifierArgument("value")
@@ -47,7 +47,7 @@
  * {@code @MinLen(2)} upon return.
  *
  * 

- * {@literal @}EnsuresMinLen(value = "field", targetValue = 2")
+ *  {@literal @}EnsuresMinLen(value = "field", targetValue = 2)
  *  public void setField(String argument) {
  *    field = "(" + argument + ")";
  *  }
diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java b/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java
index 95af23ec3761..a3ab69c41550 100644
--- a/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java
+++ b/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java
@@ -27,12 +27,12 @@
  * org.checkerframework.common.value.qual.MinLen} qualifier:
  *
  * 

- * {@literal @}PreconditionAnnotation(qualifier = MinLen.class)
- * {@literal @}Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
- * public {@literal @}interface RequiresMinLen {
- *   String[] value();
- *   {@literal @}QualifierArgument("value")
- *   int targetValue() default 0;
+ *  {@literal @}PreconditionAnnotation(qualifier = MinLen.class)
+ *  {@literal @}Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ *  public {@literal @}interface RequiresMinLen {
+ *    String[] value();
+ *    {@literal @}QualifierArgument("value")
+ *    int targetValue() default 0;
  * 
* * The {@code value} element holds the expressions to which the qualifier applies and {@code @@ -43,10 +43,10 @@ * {@code @MinLen(2)} upon entry. * *

- * {@literal @}RequiresMinLen(value = "field", targetValue = 2")
- * public char getThirdCharacter() {
- *   return field.charAt(2);
- * }
+ *  {@literal @}RequiresMinLen(value = "field", targetValue = 2")
+ *  public char getThirdCharacter() {
+ *    return field.charAt(2);
+ *  }
  * 
* * @see RequiresQualifier From 6905f4ed8a0a95322700284f4bbf37b70e2f8dff Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 11 Apr 2026 13:00:50 -0700 Subject: [PATCH 045/119] Restore `@SideEffectsOnly` --- .../dataflow/qual/SideEffectsOnly.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java new file mode 100644 index 000000000000..ab6a7dd1718f --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java @@ -0,0 +1,29 @@ +package org.checkerframework.dataflow.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.JavaExpression; + +/** + * A method annotated with the declaration annotation {@code @SideEffectsOnly("A", "B")} changes the + * value of at most the expressions A and B. All other expressions have the same value before and + * after a call to the method. + * + * @checker_framework.manual #type-refinement-purity Specifying side effects + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +public @interface SideEffectsOnly { + /** + * An upper bound on the expressions that this method might change the value of. + * + * @return the Java expressions that the annotated method might side-effect + * @checker_framework.manual #java-expressions-as-arguments Syntax of Java expressions + */ + @JavaExpression + public String[] value(); +} From e07fa4158462e3f6fdb8e357fad135e35f63880f Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 11 Apr 2026 18:46:40 -0700 Subject: [PATCH 046/119] Add imports --- .../share/classes/java/io/ObjectOutputStream.java | 1 + src/java.base/share/classes/java/lang/LiveStackFrame.java | 2 ++ .../share/classes/java/lang/LiveStackFrameInfo.java | 2 ++ src/java.base/share/classes/java/lang/StringLatin1.java | 3 +++ src/java.base/share/classes/java/lang/StringUTF16.java | 3 +++ src/java.base/share/classes/java/lang/ThreadLocal.java | 1 + src/java.base/share/classes/java/util/AbstractList.java | 1 + src/java.base/share/classes/java/util/AbstractQueue.java | 1 + .../share/classes/java/util/AbstractSequentialList.java | 7 ++++--- src/java.base/share/classes/java/util/ArrayList.java | 1 + src/java.base/share/classes/java/util/Arrays.java | 1 + .../share/classes/java/util/ImmutableCollections.java | 1 + src/java.base/share/classes/java/util/LinkedHashSet.java | 2 ++ src/java.base/share/classes/java/util/NavigableSet.java | 1 + .../share/classes/java/util/ReverseOrderDequeView.java | 3 +++ .../share/classes/java/util/ReverseOrderListView.java | 4 ++++ .../share/classes/java/util/ReverseOrderSortedMapView.java | 2 ++ .../share/classes/java/util/ReverseOrderSortedSetView.java | 2 ++ .../share/classes/java/util/SequencedCollection.java | 1 + src/java.base/share/classes/java/util/SequencedMap.java | 5 +++-- 20 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java index 7c25218bea74..1b8b465e512d 100644 --- a/src/java.base/share/classes/java/io/ObjectOutputStream.java +++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.mustcall.qual.MustCallAlias; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.PolySigned; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import java.security.AccessController; diff --git a/src/java.base/share/classes/java/lang/LiveStackFrame.java b/src/java.base/share/classes/java/lang/LiveStackFrame.java index 556ec2eb3e6c..d5aba81992b0 100644 --- a/src/java.base/share/classes/java/lang/LiveStackFrame.java +++ b/src/java.base/share/classes/java/lang/LiveStackFrame.java @@ -24,6 +24,8 @@ */ package java.lang; +import org.checkerframework.dataflow.qual.Pure; + import java.lang.StackWalker.StackFrame; import java.util.EnumSet; import java.util.Set; diff --git a/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java b/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java index 335980a6e4cd..d95db71f4055 100644 --- a/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java +++ b/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java @@ -24,6 +24,8 @@ */ package java.lang; +import org.checkerframework.dataflow.qual.Pure; + final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame { private static Object[] EMPTY_ARRAY = new Object[0]; diff --git a/src/java.base/share/classes/java/lang/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index f9586f8aaf29..c55f3a8aa319 100644 --- a/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/src/java.base/share/classes/java/lang/StringLatin1.java @@ -25,6 +25,9 @@ package java.lang; +import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.Pure; + import java.util.Arrays; import java.util.Locale; import java.util.Spliterator; diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index 9739aa9de5a9..394192376000 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -25,6 +25,9 @@ package java.lang; +import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.Pure; + import java.util.Arrays; import java.util.Locale; import java.util.Spliterator; diff --git a/src/java.base/share/classes/java/lang/ThreadLocal.java b/src/java.base/share/classes/java/lang/ThreadLocal.java index c5cdf0e453e4..29144c0e7f7a 100644 --- a/src/java.base/share/classes/java/lang/ThreadLocal.java +++ b/src/java.base/share/classes/java/lang/ThreadLocal.java @@ -26,6 +26,7 @@ package java.lang; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index 10a0755237b7..ebc730d871f7 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -43,6 +43,7 @@ import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.common.value.qual.StaticallyExecutable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index f76dc1db8253..d50e5506893c 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -43,6 +43,7 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; /** diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index dae955bcf7d6..98a3c2c6342a 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -27,10 +27,11 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; +import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -252,7 +253,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractSequentialList this, * @return an iterator over the elements in this list (in proper sequence) */ @SideEffectFree - public @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyModifiable @PolyGrowShrink @PolyNonEmpty AbstractSequentialList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractSequentialList this) { return listIterator(); } @@ -266,5 +267,5 @@ public boolean addAll(@Growable @GuardSatisfied AbstractSequentialList this, * sequence) * @throws IndexOutOfBoundsException {@inheritDoc} */ - public abstract @PolyModifiable @PolyGrowShrink ListIterator listIterator(@PolyModifiable @PolyGrowShrink AbstractSequentialList this, int index); + public abstract @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable AbstractSequentialList this, int index); } diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 17267e39925f..e9fe34602084 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -45,6 +45,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.common.value.qual.StaticallyExecutable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 56e8ca0b6b7e..2698381ad278 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -43,6 +43,7 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.checker.signedness.qual.Unsigned; import org.checkerframework.common.value.qual.MinLen; +import org.checkerframework.common.value.qual.StaticallyExecutable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java index f13c483463f4..99fca6053987 100644 --- a/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.common.value.qual.StaticallyExecutable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index dd2723084ab5..285bff113405 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -30,7 +30,9 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; +import org.checkerframework.dataflow.qual.Deterministic; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 8c600a90b269..3eff9dee501c 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -42,6 +42,7 @@ import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java index 38e62869d42a..54fec04eae4c 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java @@ -25,6 +25,9 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.function.Consumer; import java.util.function.IntFunction; import java.util.stream.Stream; diff --git a/src/java.base/share/classes/java/util/ReverseOrderListView.java b/src/java.base/share/classes/java/util/ReverseOrderListView.java index 4826354fb5ea..8302b16137d3 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderListView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderListView.java @@ -25,6 +25,10 @@ package java.util; +import org.checkerframework.common.value.qual.StaticallyExecutable; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.Objects; import java.util.function.Consumer; import java.util.function.IntFunction; diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 60c1486e15f5..8e750326b3c7 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -25,6 +25,8 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; + /** * Provides a reversed-ordered view of a SortedMap. Not serializable. * diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java index 36774ea6454e..505087b6b467 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java @@ -25,6 +25,8 @@ package java.util; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.function.Consumer; import java.util.function.IntFunction; import java.util.stream.Stream; diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index eb0960b4c4eb..3f722060ae60 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.dataflow.qual.Pure; /** diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 492615adabc0..52ae67e1a92a 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -25,14 +25,15 @@ package java.util; -import jdk.internal.util.NullableKeyValueHolder; - import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.dataflow.qual.SideEffectFree; + +import jdk.internal.util.NullableKeyValueHolder; /** * A Map that has a well-defined encounter order, that supports operations at both ends, and From e6d91b7e27d6eb16ffc96baf7df2e34aba518a4e Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 11 Apr 2026 20:18:05 -0700 Subject: [PATCH 047/119] Add imports --- README.md | 1 + .../share/classes/java/util/AbstractSequentialList.java | 1 + .../share/classes/java/util/ReverseOrderSortedSetView.java | 1 + src/java.base/share/classes/java/util/stream/DoublePipeline.java | 1 + src/java.base/share/classes/java/util/stream/IntPipeline.java | 1 + src/java.base/share/classes/java/util/stream/LongPipeline.java | 1 + .../share/classes/jdk/internal/jimage/ImageStringsReader.java | 1 + src/java.base/share/classes/jdk/internal/util/ArraysSupport.java | 1 + 8 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 383fb269c884..281d04e81396 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ merge conflicts.) ```sh cd jdk21u git pull && \ +git pull ../jdk && / git pull https://github.com/openjdk/jdk21u.git && \ git pull https://github.com/typetools/jdk.git ``` diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 98a3c2c6342a..96f4622967f6 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.dataflow.qual.Pure; diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java index 505087b6b467..0cc67edb6197 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java @@ -25,6 +25,7 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.function.Consumer; diff --git a/src/java.base/share/classes/java/util/stream/DoublePipeline.java b/src/java.base/share/classes/java/util/stream/DoublePipeline.java index bb4c3d8a8962..7b388c30bbb4 100644 --- a/src/java.base/share/classes/java/util/stream/DoublePipeline.java +++ b/src/java.base/share/classes/java/util/stream/DoublePipeline.java @@ -24,6 +24,7 @@ */ package java.util.stream; +import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.DoubleSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; diff --git a/src/java.base/share/classes/java/util/stream/IntPipeline.java b/src/java.base/share/classes/java/util/stream/IntPipeline.java index 6b3b31d80846..41a93b7485ce 100644 --- a/src/java.base/share/classes/java/util/stream/IntPipeline.java +++ b/src/java.base/share/classes/java/util/stream/IntPipeline.java @@ -24,6 +24,7 @@ */ package java.util.stream; +import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.IntSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; diff --git a/src/java.base/share/classes/java/util/stream/LongPipeline.java b/src/java.base/share/classes/java/util/stream/LongPipeline.java index ebf3e6a0acaf..9dc393080759 100644 --- a/src/java.base/share/classes/java/util/stream/LongPipeline.java +++ b/src/java.base/share/classes/java/util/stream/LongPipeline.java @@ -24,6 +24,7 @@ */ package java.util.stream; +import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.LongSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; diff --git a/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java b/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java index b07f752908c9..552ce55f05b2 100644 --- a/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java +++ b/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java @@ -25,6 +25,7 @@ package jdk.internal.jimage; +import org.checkerframework.dataflow.qual.Pure; import java.io.UTFDataFormatException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; diff --git a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java index daeb71a58cea..0a8deadac002 100644 --- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java @@ -24,6 +24,7 @@ */ package jdk.internal.util; +import org.checkerframework.dataflow.qual.Pure; import java.util.Arrays; import java.util.Collection; import jdk.internal.access.JavaLangAccess; From c0b805c517e32a41b533459905662f17727d5ac9 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 11 Apr 2026 21:14:39 -0700 Subject: [PATCH 048/119] Add imports --- .../share/classes/java/util/AbstractSequentialList.java | 3 ++- src/java.base/share/classes/java/util/SortedSet.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 96f4622967f6..31c5e77a0b6d 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -27,10 +27,11 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.index.qual.PolyGrowShrink; -import org.checkerframework.checker.index.qual.Shrinkable; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 0c82154527c3..796dee2ba8bf 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; From 5bb1743e21d9b2c8302dc3caa4088d555ce82341 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 11 Apr 2026 21:53:01 -0700 Subject: [PATCH 049/119] Fixes --- src/java.base/share/classes/java/util/Map.java | 2 +- .../share/classes/java/util/concurrent/ConcurrentHashMap.java | 2 +- .../classes/java/util/concurrent/CopyOnWriteArrayList.java | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index a21052e75bb3..732873660134 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -1818,7 +1818,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * @since 10 */ @SuppressWarnings({"rawtypes","unchecked"}) - static @Unmodifiable @PolyNonEmpty Map copyOf(@UnknownModifiablity @PolyNonEmpty Map map) { + static @Unmodifiable @PolyNonEmpty Map copyOf(@UnknownModifiability @PolyNonEmpty Map map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map)map; } else if (map.isEmpty()) { // Implicit nullcheck of map diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 2750df4daa55..f5b7edc85fcc 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4371,7 +4371,7 @@ public U searchEntries(long parallelismThreshold, * @since 1.8 */ public Map.Entry reduceEntries(long parallelismThreshold, - BiFunction, ? super Map.@Unmodifiable Entry, ? extends Map.Entry> reducer) { + BiFunction, ? super Map.Entry, ? extends Map.Entry> reducer) { if (reducer == null) throw new NullPointerException(); return new ReduceEntriesTask (null, batchFor(parallelismThreshold), 0, 0, table, 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 ac683901d348..b242e33dcf19 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -1469,7 +1469,6 @@ public boolean containsAll(Collection Date: Sun, 12 Apr 2026 09:03:40 -0700 Subject: [PATCH 050/119] Undo change to Java type --- .../share/classes/java/util/concurrent/ConcurrentHashMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index f5b7edc85fcc..0bac4223215b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4371,7 +4371,7 @@ public U searchEntries(long parallelismThreshold, * @since 1.8 */ public Map.Entry reduceEntries(long parallelismThreshold, - BiFunction, ? super Map.Entry, ? extends Map.Entry> reducer) { + BiFunction, Map.Entry, ? extends Map.Entry> reducer) { if (reducer == null) throw new NullPointerException(); return new ReduceEntriesTask (null, batchFor(parallelismThreshold), 0, 0, table, From 168d92f8ac64cb0819011f7dc0afe8698bce61f6 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sun, 12 Apr 2026 09:25:52 -0700 Subject: [PATCH 051/119] Fix YAML formatting --- .azure/azure-pipelines.yml | 630 +++++++++++++++++----------------- .azure/azure-pipelines.yml.m4 | 212 ++++++------ .azure/defs.m4 | 82 ++--- 3 files changed, 462 insertions(+), 462 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index 3307844d84e8..0e32505f2461 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -5,322 +5,322 @@ variables: jobs: -- job: build_jdk - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21-plus:latest - steps: - - bash: | - whoami - git config --get remote.origin.url - pwd - ls -al - env | sort - displayName: show environment - - bash: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors - displayName: configure - - bash: make jdk - timeoutInMinutes: 90 - displayName: make jdk - ## This works only after `make images` - # - bash: build/*/images/jdk/bin/java -version - # displayName: version - ## Don't run tests, which pass only with old version of tools (compilers, etc.). - # - bash: make -C /jdk run-test-tier1 - # displayName: make run-test-tier1 + - job: build_jdk + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21-plus:latest + steps: + - bash: | + whoami + git config --get remote.origin.url + pwd + ls -al + env | sort + displayName: show environment + - bash: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors + displayName: configure + - bash: make jdk + timeoutInMinutes: 90 + displayName: make jdk + ## This works only after `make images` + # - bash: build/*/images/jdk/bin/java -version + # displayName: version + ## Don't run tests, which pass only with old version of tools (compilers, etc.). + # - bash: make -C /jdk run-test-tier1 + # displayName: make run-test-tier1 -- job: build_jdk21u - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21-plus:latest - timeoutInMinutes: 0 - steps: - - bash: | - whoami - git config --get remote.origin.url - pwd - ls -al - env | sort - displayName: show environment - - bash: | - set -ex - if test -d /tmp/$USER/git-scripts ; \ - then git -C /tmp/$USER/git-scripts pull -q > /dev/null 2>&1 ; \ - else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git ; \ - fi - displayName: git-scripts - - bash: | - set -ex - if test -d /tmp/$USER/plume-scripts ; \ - then git -C /tmp/$USER/plume-scripts pull -q > /dev/null 2>&1 ; \ - else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/plume-scripts.git ; \ - fi - displayName: plume-scripts - # This creates ../jdk21u . - # Run `git-clone-related` without a limit on depth, because if the depth is - # too small, the merge will fail. Don't use "--filter=blob:none" because that - # leads to "fatal: remote error: filter 'combine' not supported". - - bash: | - set -ex - echo "pwd = $(pwd)" - if test -d ../jdk21u; then - echo "../jdk21u should not exist yet" - false - fi - df . - /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch - git config --global user.email "you@example.com" - git config --global user.name "Your Name" - git config --global core.longpaths true - git config --global core.protectNTFS false - cd ../jdk21u - git diff --exit-code - echo $? - displayName: clone-related-jdk21u - - bash: | - cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) - set - echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" - displayName: git merge plan - - bash: | - set -ex - git config --global user.email "you@example.com" - git config --global user.name "Your Name" - git config --global pull.ff true - git config --global pull.rebase false - git config --global core.longpaths true - git config --global core.protectNTFS false - cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) - set - echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" - cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) - displayName: git merge - - bash: cd ../jdk21u && export JT_HOME=/usr/share/jtreg && bash ./configure --with-jtreg --disable-warnings-as-errors - displayName: configure - - bash: cd ../jdk21u && make jdk - displayName: make jdk - ## This works only after `make images` - # - bash: cd ../jdk21u && build/*/images/jdk/bin/java -version - # displayName: version - # - bash: make -C /jdk21u run-test-tier1 - # timeoutInMinutes: 0 - # displayName: make run-test-tier1 - # - bash: make -C /jdk21u :test/jdk:tier1 - ## Temporarily comment out because of trouble finding junit and jasm - # - bash: cd ../jdk21u && make run-test TEST="jtreg:test/jdk:tier1" - # timeoutInMinutes: 0 - # displayName: make run-test + - job: build_jdk21u + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21-plus:latest + timeoutInMinutes: 0 + steps: + - bash: | + whoami + git config --get remote.origin.url + pwd + ls -al + env | sort + displayName: show environment + - bash: | + set -ex + if test -d /tmp/$USER/git-scripts ; \ + then git -C /tmp/$USER/git-scripts pull -q > /dev/null 2>&1 ; \ + else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git ; \ + fi + displayName: git-scripts + - bash: | + set -ex + if test -d /tmp/$USER/plume-scripts ; \ + then git -C /tmp/$USER/plume-scripts pull -q > /dev/null 2>&1 ; \ + else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/plume-scripts.git ; \ + fi + displayName: plume-scripts + # This creates ../jdk21u . + # Run `git-clone-related` without a limit on depth, because if the depth is + # too small, the merge will fail. Don't use "--filter=blob:none" because that + # leads to "fatal: remote error: filter 'combine' not supported". + - bash: | + set -ex + echo "pwd = $(pwd)" + if test -d ../jdk21u; then + echo "../jdk21u should not exist yet" + false + fi + df . + /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git config --global core.longpaths true + git config --global core.protectNTFS false + cd ../jdk21u + git diff --exit-code + echo $? + displayName: clone-related-jdk21u + - bash: | + cd ../jdk21u && git status + eval $(/tmp/$USER/plume-scripts/ci-info typetools) + set + echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" + displayName: git merge plan + - bash: | + set -ex + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git config --global pull.ff true + git config --global pull.rebase false + git config --global core.longpaths true + git config --global core.protectNTFS false + cd ../jdk21u && git status + eval $(/tmp/$USER/plume-scripts/ci-info typetools) + set + echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" + cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) + displayName: git merge + - bash: cd ../jdk21u && export JT_HOME=/usr/share/jtreg && bash ./configure --with-jtreg --disable-warnings-as-errors + displayName: configure + - bash: cd ../jdk21u && make jdk + displayName: make jdk + ## This works only after `make images` + # - bash: cd ../jdk21u && build/*/images/jdk/bin/java -version + # displayName: version + # - bash: make -C /jdk21u run-test-tier1 + # timeoutInMinutes: 0 + # displayName: make run-test-tier1 + # - bash: make -C /jdk21u :test/jdk:tier1 + ## Temporarily comment out because of trouble finding junit and jasm + # - bash: cd ../jdk21u && make run-test TEST="jtreg:test/jdk:tier1" + # timeoutInMinutes: 0 + # displayName: make run-test -- job: cftests_junit_jdk17 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) - displayName: test-cftests-junit.sh -- job: cftests_nonjunit_jdk17 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) - displayName: test-cftests-nonjunit.sh -- job: cftests_typecheck_jdk17 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) - displayName: test-typecheck.sh -- job: cftests_junit_jdk21 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) - displayName: test-cftests-junit.sh -- job: cftests_nonjunit_jdk21 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) - displayName: test-cftests-nonjunit.sh -- job: cftests_inference_jdk21 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) - displayName: test-cftests-inference.sh -- job: cftests_typecheck_jdk21 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) - displayName: test-typecheck.sh -- job: cftests_junit_jdk25 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk25:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) - displayName: test-cftests-junit.sh -- job: cftests_nonjunit_jdk25 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk25:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) - displayName: test-cftests-nonjunit.sh -- job: cftests_inference_jdk25 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk25:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) - displayName: test-cftests-inference.sh -- job: cftests_typecheck_jdk25 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk25:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) - displayName: test-typecheck.sh + - job: cftests_junit_jdk17 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) + displayName: test-cftests-junit.sh + - job: cftests_nonjunit_jdk17 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) + displayName: test-cftests-nonjunit.sh + - job: cftests_typecheck_jdk17 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) + displayName: test-typecheck.sh + - job: cftests_junit_jdk21 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) + displayName: test-cftests-junit.sh + - job: cftests_nonjunit_jdk21 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) + displayName: test-cftests-nonjunit.sh + - job: cftests_inference_jdk21 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) + displayName: test-cftests-inference.sh + - job: cftests_typecheck_jdk21 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) + displayName: test-typecheck.sh + - job: cftests_junit_jdk25 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) + displayName: test-cftests-junit.sh + - job: cftests_nonjunit_jdk25 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) + displayName: test-cftests-nonjunit.sh + - job: cftests_inference_jdk25 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) + displayName: test-cftests-inference.sh + - job: cftests_typecheck_jdk25 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) + displayName: test-typecheck.sh -- job: test_daikon_part1 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - timeoutInMinutes: 70 - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part1.sh) - displayName: test-daikon-part1.sh -- job: test_daikon_part2 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - timeoutInMinutes: 70 - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part2.sh) - displayName: test-daikon-part2.sh -- job: test_daikon_part3 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - timeoutInMinutes: 70 - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part3.sh) - displayName: test-daikon-part3.sh + - job: test_daikon_part1 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + timeoutInMinutes: 70 + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part1.sh) + displayName: test-daikon-part1.sh + - job: test_daikon_part2 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + timeoutInMinutes: 70 + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part2.sh) + displayName: test-daikon-part2.sh + - job: test_daikon_part3 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + timeoutInMinutes: 70 + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part3.sh) + displayName: test-daikon-part3.sh -- job: test_plume_lib - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-plume-lib.sh) - displayName: test-plume-lib.sh + - job: test_plume_lib + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-plume-lib.sh) + displayName: test-plume-lib.sh diff --git a/.azure/azure-pipelines.yml.m4 b/.azure/azure-pipelines.yml.m4 index d7aaea4c3482..c152a8c5e538 100644 --- a/.azure/azure-pipelines.yml.m4 +++ b/.azure/azure-pipelines.yml.m4 @@ -8,113 +8,113 @@ variables: jobs: -- job: build_jdk - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21-plus:latest - steps: - - bash: | - whoami - git config --get remote.origin.url - pwd - ls -al - env | sort - displayName: show environment - - bash: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors - displayName: configure - - bash: make jdk - timeoutInMinutes: 90 - displayName: make jdk - ## This works only after `make images` - # - bash: build/*/images/jdk/bin/java -version - # displayName: version - ## Don't run tests, which pass only with old version of tools (compilers, etc.). - # - bash: make -C /jdk run-test-tier1 - # displayName: make run-test-tier1 + - job: build_jdk + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21-plus:latest + steps: + - bash: | + whoami + git config --get remote.origin.url + pwd + ls -al + env | sort + displayName: show environment + - bash: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors + displayName: configure + - bash: make jdk + timeoutInMinutes: 90 + displayName: make jdk + ## This works only after `make images` + # - bash: build/*/images/jdk/bin/java -version + # displayName: version + ## Don't run tests, which pass only with old version of tools (compilers, etc.). + # - bash: make -C /jdk run-test-tier1 + # displayName: make run-test-tier1 -- job: build_jdk21u - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk21-plus:latest - timeoutInMinutes: 0 - steps: - - bash: | - whoami - git config --get remote.origin.url - pwd - ls -al - env | sort - displayName: show environment - - bash: | - set -ex - if test -d /tmp/$USER/git-scripts ; \ - then git -C /tmp/$USER/git-scripts pull -q > /dev/null 2>&1 ; \ - else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git ; \ - fi - displayName: git-scripts - - bash: | - set -ex - if test -d /tmp/$USER/plume-scripts ; \ - then git -C /tmp/$USER/plume-scripts pull -q > /dev/null 2>&1 ; \ - else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/plume-scripts.git ; \ - fi - displayName: plume-scripts - # This creates ../jdk21u . - # Run `git-clone-related` without a limit on depth, because if the depth is - # too small, the merge will fail. Don't use "--filter=blob:none" because that - # leads to "fatal: remote error: filter 'combine' not supported". - - bash: | - set -ex - echo "pwd = $(pwd)" - if test -d ../jdk21u; then - echo "../jdk21u should not exist yet" - false - fi - df . - /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch - git config --global user.email "you@example.com" - git config --global user.name "Your Name" - git config --global core.longpaths true - git config --global core.protectNTFS false - cd ../jdk21u - git diff --exit-code - echo $? - displayName: clone-related-jdk21u - - bash: | - cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) - set - echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" - displayName: git merge plan - - bash: | - set -ex - git config --global user.email "you@example.com" - git config --global user.name "Your Name" - git config --global pull.ff true - git config --global pull.rebase false - git config --global core.longpaths true - git config --global core.protectNTFS false - cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) - set - echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" - cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) - displayName: git merge - - bash: cd ../jdk21u && export JT_HOME=/usr/share/jtreg && bash ./configure --with-jtreg --disable-warnings-as-errors - displayName: configure - - bash: cd ../jdk21u && make jdk - displayName: make jdk - ## This works only after `make images` - # - bash: cd ../jdk21u && build/*/images/jdk/bin/java -version - # displayName: version - # - bash: make -C /jdk21u run-test-tier1 - # timeoutInMinutes: 0 - # displayName: make run-test-tier1 - # - bash: make -C /jdk21u :test/jdk:tier1 - ## Temporarily comment out because of trouble finding junit and jasm - # - bash: cd ../jdk21u && make run-test TEST="jtreg:test/jdk:tier1" - # timeoutInMinutes: 0 - # displayName: make run-test + - job: build_jdk21u + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk21-plus:latest + timeoutInMinutes: 0 + steps: + - bash: | + whoami + git config --get remote.origin.url + pwd + ls -al + env | sort + displayName: show environment + - bash: | + set -ex + if test -d /tmp/$USER/git-scripts ; \ + then git -C /tmp/$USER/git-scripts pull -q > /dev/null 2>&1 ; \ + else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git ; \ + fi + displayName: git-scripts + - bash: | + set -ex + if test -d /tmp/$USER/plume-scripts ; \ + then git -C /tmp/$USER/plume-scripts pull -q > /dev/null 2>&1 ; \ + else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/plume-scripts.git ; \ + fi + displayName: plume-scripts + # This creates ../jdk21u . + # Run `git-clone-related` without a limit on depth, because if the depth is + # too small, the merge will fail. Don't use "--filter=blob:none" because that + # leads to "fatal: remote error: filter 'combine' not supported". + - bash: | + set -ex + echo "pwd = $(pwd)" + if test -d ../jdk21u; then + echo "../jdk21u should not exist yet" + false + fi + df . + /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git config --global core.longpaths true + git config --global core.protectNTFS false + cd ../jdk21u + git diff --exit-code + echo $? + displayName: clone-related-jdk21u + - bash: | + cd ../jdk21u && git status + eval $(/tmp/$USER/plume-scripts/ci-info typetools) + set + echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" + displayName: git merge plan + - bash: | + set -ex + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git config --global pull.ff true + git config --global pull.rebase false + git config --global core.longpaths true + git config --global core.protectNTFS false + cd ../jdk21u && git status + eval $(/tmp/$USER/plume-scripts/ci-info typetools) + set + echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" + cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) + displayName: git merge + - bash: cd ../jdk21u && export JT_HOME=/usr/share/jtreg && bash ./configure --with-jtreg --disable-warnings-as-errors + displayName: configure + - bash: cd ../jdk21u && make jdk + displayName: make jdk + ## This works only after `make images` + # - bash: cd ../jdk21u && build/*/images/jdk/bin/java -version + # displayName: version + # - bash: make -C /jdk21u run-test-tier1 + # timeoutInMinutes: 0 + # displayName: make run-test-tier1 + # - bash: make -C /jdk21u :test/jdk:tier1 + ## Temporarily comment out because of trouble finding junit and jasm + # - bash: cd ../jdk21u && make run-test TEST="jtreg:test/jdk:tier1" + # timeoutInMinutes: 0 + # displayName: make run-test cftests_job(junit, cftests-junit, 17) cftests_job(nonjunit, cftests-nonjunit, 17) diff --git a/.azure/defs.m4 b/.azure/defs.m4 index 1d651873c282..0653a1c78481 100644 --- a/.azure/defs.m4 +++ b/.azure/defs.m4 @@ -12,20 +12,20 @@ ifelse([uncomment the next line to use the "testing" Docker images])dnl ifelse([define([docker_testing], [-testing])])dnl dnl define([cftests_job], [dnl -- job: cftests_$1_jdk$3 - timeoutInMinutes: 120 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk$3:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-$2.sh) - displayName: test-$2.sh])dnl + - job: cftests_$1_jdk$3 + timeoutInMinutes: 120 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk$3:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-$2.sh) + displayName: test-$2.sh])dnl dnl define([junit_job], [dnl - job: junit_jdk$1 @@ -150,35 +150,35 @@ ifelse($1,canary_version,[dnl displayName: test-typecheck.sh])])dnl dnl define([daikon_job], [dnl -- job: test_daikon_part$1 - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - timeoutInMinutes: 70 - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part$1.sh) - displayName: test-daikon-part$1.sh])dnl + - job: test_daikon_part$1 + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + timeoutInMinutes: 70 + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part$1.sh) + displayName: test-daikon-part$1.sh])dnl dnl define([plume_lib_job], [dnl -- job: test_plume_lib - pool: - vmImage: 'ubuntu-latest' - container: mdernst/cf-ubuntu-jdk17:latest - steps: - - checkout: self - fetchDepth: 25 - - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - displayName: clone git-scripts - - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework - displayName: clone checker-framework - - bash: (cd ../checker-framework && checker/bin-devel/test-plume-lib.sh) - displayName: test-plume-lib.sh])dnl + - job: test_plume_lib + pool: + vmImage: 'ubuntu-latest' + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - checkout: self + fetchDepth: 25 + - bash: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + displayName: clone git-scripts + - bash: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + displayName: clone checker-framework + - bash: (cd ../checker-framework && checker/bin-devel/test-plume-lib.sh) + displayName: test-plume-lib.sh])dnl ifelse([ Local Variables: eval: (add-hook 'after-save-hook '(lambda () (run-command nil "make")) nil 'local) From 8fd7a26529f8b1b5dbc78d94c9021b84adb3b0ff Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sun, 12 Apr 2026 09:32:17 -0700 Subject: [PATCH 052/119] Add canary job --- .azure/azure-pipelines.yml | 40 +++++++++++++++++++++++++++++++++++ .azure/azure-pipelines.yml.m4 | 10 +++++++++ .azure/defs.m4 | 23 ++++++++++++++------ 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index 0e32505f2461..faf84061d065 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -113,7 +113,19 @@ jobs: # timeoutInMinutes: 0 # displayName: make run-test + - job: canary_jobs + dependsOn: + - build_jdk + - build_jdk21u + pool: + vmImage: 'ubuntu-latest' + steps: + - bash: true + displayName: canary_jobs + - job: cftests_junit_jdk17 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -128,6 +140,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) displayName: test-cftests-junit.sh - job: cftests_nonjunit_jdk17 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -142,6 +156,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) displayName: test-cftests-nonjunit.sh - job: cftests_typecheck_jdk17 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -156,6 +172,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) displayName: test-typecheck.sh - job: cftests_junit_jdk21 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -170,6 +188,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) displayName: test-cftests-junit.sh - job: cftests_nonjunit_jdk21 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -184,6 +204,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) displayName: test-cftests-nonjunit.sh - job: cftests_inference_jdk21 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -198,6 +220,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) displayName: test-cftests-inference.sh - job: cftests_typecheck_jdk21 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -212,6 +236,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) displayName: test-typecheck.sh - job: cftests_junit_jdk25 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -226,6 +252,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) displayName: test-cftests-junit.sh - job: cftests_nonjunit_jdk25 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -240,6 +268,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) displayName: test-cftests-nonjunit.sh - job: cftests_inference_jdk25 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -254,6 +284,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) displayName: test-cftests-inference.sh - job: cftests_typecheck_jdk25 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -269,6 +301,8 @@ jobs: displayName: test-typecheck.sh - job: test_daikon_part1 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk17:latest @@ -283,6 +317,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part1.sh) displayName: test-daikon-part1.sh - job: test_daikon_part2 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk17:latest @@ -297,6 +333,8 @@ jobs: - bash: (cd ../checker-framework && checker/bin-devel/test-daikon-part2.sh) displayName: test-daikon-part2.sh - job: test_daikon_part3 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk17:latest @@ -312,6 +350,8 @@ jobs: displayName: test-daikon-part3.sh - job: test_plume_lib + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk17:latest diff --git a/.azure/azure-pipelines.yml.m4 b/.azure/azure-pipelines.yml.m4 index c152a8c5e538..8dd5ec8fca13 100644 --- a/.azure/azure-pipelines.yml.m4 +++ b/.azure/azure-pipelines.yml.m4 @@ -116,6 +116,16 @@ jobs: # timeoutInMinutes: 0 # displayName: make run-test + - job: canary_jobs + dependsOn: + - build_jdk + - build_jdk21u + pool: + vmImage: 'ubuntu-latest' + steps: + - bash: true + displayName: canary_jobs + cftests_job(junit, cftests-junit, 17) cftests_job(nonjunit, cftests-nonjunit, 17) cftests_job(typecheck, typecheck, 17) diff --git a/.azure/defs.m4 b/.azure/defs.m4 index 0653a1c78481..e3cbeef84b90 100644 --- a/.azure/defs.m4 +++ b/.azure/defs.m4 @@ -7,12 +7,15 @@ define([canary_os], [ubuntu])dnl define([canary_version], [25])dnl define([latest_version], [25])dnl define([canary_test], [canary_os[]canary_version])dnl +define([jdku_version], [21u])dnl define([docker_testing], [])dnl ifelse([uncomment the next line to use the "testing" Docker images])dnl ifelse([define([docker_testing], [-testing])])dnl dnl define([cftests_job], [dnl - job: cftests_$1_jdk$3 + dependsOn: + - canary_jobs timeoutInMinutes: 120 pool: vmImage: 'ubuntu-latest' @@ -29,9 +32,9 @@ define([cftests_job], [dnl dnl define([junit_job], [dnl - job: junit_jdk$1 -ifelse($1,canary_version,,[ dependsOn: + dependsOn: - canary_jobs - - junit_jdk[]canary_version +ifelse($1,canary_version,,[ - junit_jdk[]canary_version ])dnl pool: vmImage: 'ubuntu-latest' @@ -45,9 +48,9 @@ ifelse($1,canary_version,,[ dependsOn: dnl define([nonjunit_job], [dnl - job: nonjunit_jdk$1 -ifelse($1,canary_version,,[ dependsOn: + dependsOn: - canary_jobs - - nonjunit_jdk[]canary_version +ifelse($1,canary_version,,[ - nonjunit_jdk[]canary_version ])dnl pool: vmImage: 'ubuntu-latest' @@ -62,6 +65,8 @@ define([inference_job], [dnl ifelse($1,canary_version,[dnl # Split into part1 and part2 only for the inference job that "canary_jobs" depends on. - job: inference_part1_jdk$1 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk$1[]docker_testing:latest @@ -101,9 +106,9 @@ ifelse($1,canary_version,[dnl dnl define([misc_job], [dnl - job: misc_jdk$1 -ifelse($1,canary_version,,$1,latest_version,,[ dependsOn: + dependsOn: - canary_jobs - - misc_jdk[]canary_version +ifelse($1,canary_version,,$1,latest_version,,[ - misc_jdk[]canary_version ])dnl pool: vmImage: 'ubuntu-latest' @@ -118,6 +123,8 @@ dnl define([typecheck_job], [dnl ifelse($1,canary_version,[dnl - job: typecheck_part1_jdk$1 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk$1[]docker_testing:latest @@ -151,6 +158,8 @@ ifelse($1,canary_version,[dnl dnl define([daikon_job], [dnl - job: test_daikon_part$1 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk17:latest @@ -167,6 +176,8 @@ define([daikon_job], [dnl dnl define([plume_lib_job], [dnl - job: test_plume_lib + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk17:latest From 6ee41a6c1d91c7e17976b5033f36c824c89b4b5e Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sun, 12 Apr 2026 12:20:36 -0700 Subject: [PATCH 053/119] Add missing dependency --- .azure/defs.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure/defs.m4 b/.azure/defs.m4 index e3cbeef84b90..345d4ed21584 100644 --- a/.azure/defs.m4 +++ b/.azure/defs.m4 @@ -7,7 +7,6 @@ define([canary_os], [ubuntu])dnl define([canary_version], [25])dnl define([latest_version], [25])dnl define([canary_test], [canary_os[]canary_version])dnl -define([jdku_version], [21u])dnl define([docker_testing], [])dnl ifelse([uncomment the next line to use the "testing" Docker images])dnl ifelse([define([docker_testing], [-testing])])dnl @@ -77,6 +76,8 @@ ifelse($1,canary_version,[dnl - bash: export ORG_GRADLE_PROJECT_jdkTestVersion=$1 && ./checker/bin-devel/test-cftests-inference-part1.sh displayName: test-cftests-inference-part1.sh - job: inference_part2_jdk$1 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk$1[]docker_testing:latest @@ -134,6 +135,8 @@ ifelse($1,canary_version,[dnl - bash: export ORG_GRADLE_PROJECT_jdkTestVersion=$1 && ./checker/bin-devel/test-typecheck-part1.sh displayName: test-typecheck-part1.sh - job: typecheck_part2_jdk$1 + dependsOn: + - canary_jobs pool: vmImage: 'ubuntu-latest' container: mdernst/cf-ubuntu-jdk$1[]docker_testing:latest From 441b6c7e5819e958342b93aa731d4bb181d964a9 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sun, 12 Apr 2026 12:26:12 -0700 Subject: [PATCH 054/119] Add import --- .../share/classes/javax/swing/DefaultListModel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/java.desktop/share/classes/javax/swing/DefaultListModel.java b/src/java.desktop/share/classes/javax/swing/DefaultListModel.java index d75de937e94b..059d0463d2d7 100644 --- a/src/java.desktop/share/classes/javax/swing/DefaultListModel.java +++ b/src/java.desktop/share/classes/javax/swing/DefaultListModel.java @@ -25,6 +25,8 @@ package javax.swing; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.Vector; import java.util.Collection; import java.util.Enumeration; From e6567855928677404cdd84626966738106591eed Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 12 Apr 2026 20:42:49 -0700 Subject: [PATCH 055/119] annotated stack.java which extends vector --- src/java.base/share/classes/java/util/Stack.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 4a960c5b90db..50ec5dfa7ae1 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -27,6 +27,9 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -57,12 +60,12 @@ * @since 1.0 */ @CFComment({"lock/nullness: permit null elements"}) -@AnnotatedFor({"lock", "nullness"}) +@AnnotatedFor({"lock", "nullness", "modifiability"}) public class Stack extends Vector { /** * Creates an empty Stack. */ - public Stack() { + public @Modifiable Stack() { } /** @@ -75,7 +78,7 @@ public Stack() { * @return the {@code item} argument. * @see java.util.Vector#addElement */ - public E push(@GuardSatisfied Stack this, E item) { + public E push(@Growable @GuardSatisfied Stack this, E item) { addElement(item); return item; @@ -89,7 +92,7 @@ public E push(@GuardSatisfied Stack this, E item) { * of the {@code Vector} object). * @throws EmptyStackException if this stack is empty. */ - public synchronized E pop(@GuardSatisfied @NonEmpty @CanShrink Stack this) { + public synchronized E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Stack this) { E obj; int len = size(); From d559eb50362a7a7f789bcee3b8fe5d93f953de7a Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 14 Apr 2026 08:19:08 -0700 Subject: [PATCH 056/119] Fix line continuation character --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 281d04e81396..42f7f7bb1ee7 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ merge conflicts.) ```sh cd jdk21u git pull && \ -git pull ../jdk && / +git pull ../jdk && \ git pull https://github.com/openjdk/jdk21u.git && \ git pull https://github.com/typetools/jdk.git ``` From 11790824c37f8510fa01112ff38b4a49d817cb82 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Fri, 17 Apr 2026 17:55:33 -0700 Subject: [PATCH 057/119] annotated keyset, values, and entryset to return @Ungrowable set. --- .../share/classes/java/util/AbstractMap.java | 7 ++++--- src/java.base/share/classes/java/util/EnumMap.java | 7 ++++--- src/java.base/share/classes/java/util/HashMap.java | 7 ++++--- .../share/classes/java/util/Hashtable.java | 7 ++++--- .../share/classes/java/util/IdentityHashMap.java | 7 ++++--- .../share/classes/java/util/LinkedHashMap.java | 13 +++++++------ src/java.base/share/classes/java/util/Map.java | 7 ++++--- .../share/classes/java/util/NavigableMap.java | 5 +++-- .../share/classes/java/util/SequencedMap.java | 7 ++++--- .../share/classes/java/util/SortedMap.java | 7 ++++--- src/java.base/share/classes/java/util/TreeMap.java | 11 ++++++----- .../share/classes/java/util/WeakHashMap.java | 7 ++++--- .../java/util/concurrent/ConcurrentHashMap.java | 5 +++-- .../util/concurrent/ConcurrentNavigableMap.java | 7 ++++--- .../java/util/concurrent/ConcurrentSkipListMap.java | 11 ++++++----- 15 files changed, 65 insertions(+), 50 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 38364b4bc078..d0b073222596 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.modifiability.qual.Replaceale; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; @@ -384,7 +385,7 @@ public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { * method will not all return the same set. */ @SideEffectFree - public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { + public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { @@ -451,7 +452,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - public @PolyShrink Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { @@ -502,7 +503,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - public abstract @PolyShrink Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); + public abstract @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index b02d5e6e6c13..720f97c248d1 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -412,7 +413,7 @@ public void clear(@Shrinkable EnumMap this) { * * @return a set view of the keys contained in this enum map */ - public @PolyShrink Set keySet(@PolyShrink EnumMap this) { + public @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -455,7 +456,7 @@ public void clear(@Shrinkable KeySet this) { * * @return a collection view of the values contained in this map */ - public @PolyShrink Collection values(@PolyShrink EnumMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -505,7 +506,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyModifiable EnumMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 103af8a27a01..fb7df44c8e74 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -945,7 +946,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { + public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1079,7 +1080,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - public @PolyShrink Collection values(@PolyShrink @GuardSatisfied HashMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1143,7 +1144,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index aecededa6607..77bb0cc22b24 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -696,7 +697,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { + public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); return keySet; @@ -741,7 +742,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); return entrySet; @@ -826,7 +827,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @PolyShrink Collection values(@PolyShrink @GuardSatisfied Hashtable this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), this); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 1a48ce607ba1..90975ff87cdd 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1021,7 +1022,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1135,7 +1136,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - public @PolyShrink Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1250,7 +1251,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 34f72f2b77d2..3ee2dddd18d7 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -649,7 +650,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - public @PolyShrink Set keySet(@PolyShrink LinkedHashMap this) { + public @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { return sequencedKeySet(); } @@ -662,7 +663,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return {@inheritDoc} * @since 21 */ - public @PolyShrink SequencedSet sequencedKeySet(@PolyShrink LinkedHashMap this) { + public @PolyShrink @Ungrowable SequencedSet sequencedKeySet(@PolyShrink LinkedHashMap this) { Set ks = keySet; if (ks == null) { SequencedSet sks = new LinkedKeySet(false); @@ -803,7 +804,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ - public @PolyShrink Collection values(@PolyShrink LinkedHashMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { return sequencedValues(); } @@ -816,7 +817,7 @@ public SequencedSet reversed() { * @return {@inheritDoc} * @since 21 */ - public @PolyShrink SequencedCollection sequencedValues(@PolyShrink LinkedHashMap this) { + public @PolyShrink @Ungrowable SequencedCollection sequencedValues(@PolyShrink LinkedHashMap this) { Collection vs = values; if (vs == null) { SequencedCollection svs = new LinkedValues(false); @@ -914,7 +915,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -927,7 +928,7 @@ public SequencedCollection reversed() { * @return {@inheritDoc} * @since 21 */ - public @PolyShrink SequencedSet> sequencedEntrySet(@PolyModifiable LinkedHashMap this) { + public @PolyShrink @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable LinkedHashMap this) { Set> es = entrySet; if (es == null) { SequencedSet> ses = new LinkedEntrySet(false); diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 1600c0c611e1..5e6dde92c14a 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -36,6 +36,7 @@ import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -397,7 +398,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @PolyShrink @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -415,7 +416,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @PolyShrink @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -434,7 +435,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @PolyShrink @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index e110fe69db53..3fa57771f062 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -298,7 +299,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @PolyShrink NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); + @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -315,7 +316,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @PolyShrink NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); + @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); /** * Returns a view of the portion of this map whose keys range from diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 8a1f25ebc733..f1f35d6b4a7c 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; /** @@ -278,7 +279,7 @@ default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { * * @return a {@code SequencedSet} view of this map's {@code keySet} */ - default @PolyShrink SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { + default @PolyShrink @Ungrowable SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { Collection view() { return SequencedMap.this.keySet(); @@ -311,7 +312,7 @@ public int hashCode() { * * @return a {@code SequencedCollection} view of this map's {@code values} collection */ - default @PolyShrink SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { + default @PolyShrink @Ungrowable SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { Collection view() { return SequencedMap.this.values(); @@ -337,7 +338,7 @@ public SequencedCollection reversed() { * * @return a {@code SequencedSet} view of this map's {@code entrySet} */ - default @PolyShrink SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { + default @PolyShrink @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { class SeqEntrySet extends AbstractMap.ViewCollection> implements SequencedSet> { Collection> view() { diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 4958e5a52acf..a162f0c20047 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; @@ -262,7 +263,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); + @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -283,7 +284,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @PolyShrink Collection values(@PolyShrink @GuardSatisfied SortedMap this); + @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -304,7 +305,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); + @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** * Throws {@code UnsupportedOperationException}. The encounter order induced by this diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index bea1bdc2742a..89bd8b10036b 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1159,7 +1160,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. It does not support the {@code add} or {@code addAll} * operations. */ - public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1167,7 +1168,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @PolyShrink NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } @@ -1176,7 +1177,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @PolyShrink NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1201,7 +1202,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ - public @PolyShrink Collection values(@PolyShrink @GuardSatisfied TreeMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1233,7 +1234,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 8f17e4c9a8c8..abd070660b78 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -909,7 +910,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - public @PolyShrink Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { + public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -968,7 +969,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @PolyShrink Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1019,7 +1020,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 1affce11f660..fcc9193aeac0 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -40,6 +40,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1293,7 +1294,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - public @PolyShrink Collection values(@PolyShrink ConcurrentHashMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; return values = new ValuesView(this); @@ -1317,7 +1318,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyShrink ConcurrentHashMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index cd3d406c2bfd..cdcd39810ac5 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.SideEffectFree; import java.util.NavigableMap; @@ -145,7 +146,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @PolyShrink NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); + @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -165,7 +166,7 @@ public interface ConcurrentNavigableMap * * @return a navigable set view of the keys in this map */ - @PolyShrink NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); + @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -184,5 +185,5 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @PolyShrink NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); + @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 8397bc488ab4..34ebceb73b5b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -41,6 +41,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1639,14 +1640,14 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ - public @PolyShrink NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { + public @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); } @SideEffectFree - public @PolyShrink NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { + public @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); @@ -1671,7 +1672,7 @@ else if (doRemove(key, v) != null) *

The view's iterators and spliterators are * weakly consistent. */ - public @PolyShrink Collection values(@PolyShrink ConcurrentSkipListMap this) { + public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; return values = new Values<>(this); @@ -1705,7 +1706,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - public @PolyShrink Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { + public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1720,7 +1721,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - public @PolyShrink NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { + public @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } From 10a022c836154fc87c6f707cec67ae1517cfca7d Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Tue, 21 Apr 2026 23:04:15 -0700 Subject: [PATCH 058/119] add ci.yml in .github --- .github/workflows/ci.yml | 373 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000000..5e2e551a76e0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,373 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + build_jdk: + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk21-plus:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: show environment + run: | + whoami + git config --get remote.origin.url + pwd + ls -al + env | sort + - name: configure + run: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors + - name: make jdk + timeout-minutes: 90 + run: make jdk + + build_jdk21u: + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk21-plus:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: show environment + run: | + whoami + git config --get remote.origin.url + pwd + ls -al + env | sort + - name: git-scripts + run: | + set -ex + if test -d /tmp/$USER/git-scripts ; \ + then git -C /tmp/$USER/git-scripts pull -q > /dev/null 2>&1 ; \ + else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git ; \ + fi + - name: plume-scripts + run: | + set -ex + if test -d /tmp/$USER/plume-scripts ; \ + then git -C /tmp/$USER/plume-scripts pull -q > /dev/null 2>&1 ; \ + else mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/plume-scripts.git ; \ + fi + - name: clone-related-jdk21u + run: | + set -ex + echo "pwd = $(pwd)" + if test -d ../jdk21u; then + echo "../jdk21u should not exist yet" + false + fi + df . + /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git config --global core.longpaths true + git config --global core.protectNTFS false + cd ../jdk21u + git diff --exit-code + echo $? + - name: git merge plan + run: | + cd ../jdk21u && git status + eval $(/tmp/$USER/plume-scripts/ci-info typetools) + set + echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" + - name: git merge + run: | + set -ex + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git config --global pull.ff true + git config --global pull.rebase false + git config --global core.longpaths true + git config --global core.protectNTFS false + cd ../jdk21u && git status + eval $(/tmp/$USER/plume-scripts/ci-info typetools) + set + echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" + cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) + - name: configure + run: cd ../jdk21u && export JT_HOME=/usr/share/jtreg && bash ./configure --with-jtreg --disable-warnings-as-errors + - name: make jdk + run: cd ../jdk21u && make jdk + + canary_jobs: + needs: + - build_jdk + - build_jdk21u + runs-on: ubuntu-latest + steps: + - name: canary_jobs + run: true + + cftests_junit_jdk17: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-junit.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) + + cftests_nonjunit_jdk17: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-nonjunit.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) + + cftests_typecheck_jdk17: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-typecheck.sh + run: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) + + cftests_junit_jdk21: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-junit.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) + + cftests_nonjunit_jdk21: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-nonjunit.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) + + cftests_inference_jdk21: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-inference.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) + + cftests_typecheck_jdk21: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk21:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-typecheck.sh + run: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) + + cftests_junit_jdk25: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-junit.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-junit.sh) + + cftests_nonjunit_jdk25: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-nonjunit.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-nonjunit.sh) + + cftests_inference_jdk25: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-cftests-inference.sh + run: (cd ../checker-framework && checker/bin-devel/test-cftests-inference.sh) + + cftests_typecheck_jdk25: + needs: + - canary_jobs + timeout-minutes: 120 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk25:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-typecheck.sh + run: (cd ../checker-framework && checker/bin-devel/test-typecheck.sh) + + test_daikon_part1: + needs: + - canary_jobs + timeout-minutes: 70 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-daikon-part1.sh + run: (cd ../checker-framework && checker/bin-devel/test-daikon-part1.sh) + + test_daikon_part2: + needs: + - canary_jobs + timeout-minutes: 70 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-daikon-part2.sh + run: (cd ../checker-framework && checker/bin-devel/test-daikon-part2.sh) + + test_daikon_part3: + needs: + - canary_jobs + timeout-minutes: 70 + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-daikon-part3.sh + run: (cd ../checker-framework && checker/bin-devel/test-daikon-part3.sh) + + test_plume_lib: + needs: + - canary_jobs + runs-on: ubuntu-latest + container: mdernst/cf-ubuntu-jdk17:latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 25 + - name: clone git-scripts + run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git + - name: clone checker-framework + run: /tmp/$USER/git-scripts/git-clone-related typetools checker-framework + - name: test-plume-lib.sh + run: (cd ../checker-framework && checker/bin-devel/test-plume-lib.sh) From f533200a1c09a913199b3197fd42d3fb76d6a9d0 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Tue, 21 Apr 2026 23:16:04 -0700 Subject: [PATCH 059/119] update ci.yml: make run steps execute in bash without -e --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e2e551a76e0..9edbcd9d155b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,10 @@ on: pull_request: workflow_dispatch: +defaults: + run: + shell: bash --noprofile --norc {0} + jobs: build_jdk: runs-on: ubuntu-latest From 56399df942b372c891458a51965567898478e076 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 22 Apr 2026 00:17:27 -0700 Subject: [PATCH 060/119] synced checker-qual.jar --- checker-qual.jar | Bin 286009 -> 289340 bytes .../modifiability/qual/BottomGrow.java | 21 +++++++++++++ .../modifiability/qual/BottomReplace.java | 21 +++++++++++++ .../modifiability/qual/BottomShrink.java | 21 +++++++++++++ .../modifiability/qual/Ungrowable.java | 22 +++++++++++++ .../modifiability/qual/UnknownGrow.java | 4 +-- .../qual/UnknownModifiability.java | 3 +- .../modifiability/qual/UnknownReplace.java | 6 ++-- .../modifiability/qual/UnknownShrink.java | 6 ++-- .../modifiability/qual/Unmodifiable.java | 6 ++-- .../modifiability/qual/Unreplaceable.java | 22 +++++++++++++ .../modifiability/qual/Unshrinkable.java | 22 +++++++++++++ .../dataflow/qual/SideEffectsOnly.java | 29 ------------------ .../qual/DoesNotUnrefineReceiver.java | 2 +- 14 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java delete mode 100644 src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java rename src/java.base/share/classes/org/checkerframework/{dataflow => framework}/qual/DoesNotUnrefineReceiver.java (96%) diff --git a/checker-qual.jar b/checker-qual.jar index 8c13f44b86d88603313b832898f97b0f711bba7d..811cd283e7085f1b8a9a1754055e7c19f0a7affd 100644 GIT binary patch delta 11100 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 diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java new file mode 100644 index 000000000000..a01b989a8664 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java @@ -0,0 +1,21 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The bottom qualifier in the Grow hierarchy. + * + *

Programmers should rarely write this qualifier. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({Growable.class, Ungrowable.class}) +public @interface BottomGrow {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java new file mode 100644 index 000000000000..a2609e3558de --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java @@ -0,0 +1,21 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The bottom qualifier in the Replace hierarchy. + * + *

Programmers should rarely write this qualifier. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({Replaceable.class, Unreplaceable.class}) +public @interface BottomReplace {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java new file mode 100644 index 000000000000..3cf5d6902f6e --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java @@ -0,0 +1,21 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The bottom qualifier in the Shrink hierarchy. + * + *

Programmers should rarely write this qualifier. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({Shrinkable.class, Unshrinkable.class}) +public @interface BottomShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java new file mode 100644 index 000000000000..24348a29d853 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling grow operations such as {@code add}, {@code addAll}, etc. on this collection will throw + * {@link UnsupportedOperationException}. + * + *

No guarantees are made about shrink or replace operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownGrow.class) +public @interface Ungrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java index 30f3c460deec..c71e04417b1c 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java @@ -9,8 +9,8 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the Grow hierarchy. Represents an unknown or absent grow capability. The - * checker cannot determine whether the collection supports grow operations such as {@code add}. + * The top qualifier in the Grow hierarchy. Represents unknown grow capability. The checker cannot + * determine whether the collection supports grow operations such as {@code add}. * *

This is the default qualifier for unannotated types in the Grow hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java index f653f09d2d03..502805c4a134 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java @@ -12,8 +12,7 @@ * collection is growable, shrinkable, or replaceable. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @UnknownGrow @UnknownShrink @UnknownReplace} on each annotated type. It is equivalent to - * {@link Unmodifiable}. + * {@code @UnknownGrow @UnknownShrink @UnknownReplace} on each annotated type. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java index a793d64f521f..164002371c5b 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java @@ -9,9 +9,9 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the Replace hierarchy. Represents an unknown or absent replace capability. - * The checker cannot determine whether the collection supports replace operations such as {@code - * set} or {@code replaceAll}. + * The top qualifier in the Replace hierarchy. Represents unknown replace capability. The checker + * cannot determine whether the collection supports replace operations such as {@code set} or {@code + * replaceAll}. * *

This is the default qualifier for unannotated types in the Replace hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java index 7f87345b521c..68f5918995e3 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java @@ -9,9 +9,9 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the Shrink hierarchy. Represents an unknown or absent shrink capability. The - * checker cannot determine whether the collection supports shrink operations such as {@code remove} - * or {@code clear}. + * The top qualifier in the Shrink hierarchy. Represents unknown shrink capability. The checker + * cannot determine whether the collection supports shrink operations such as {@code remove} or + * {@code clear}. * *

This is the default qualifier for unannotated types in the Shrink hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index f5252ff71572..f8d2c6fdc043 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -7,12 +7,12 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @UnknownGrow @UnknownShrink @UnknownReplace}. Calling any - * mutating operation on this collection (growing, shrinking, or replacing) will throw {@link + * Convenience alias meaning {@code @Ungrowable @Unshrinkable @Unreplaceable}. Calling any mutating + * operation on this collection (growing, shrinking, or replacing) will throw {@link * UnsupportedOperationException}. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @UnknownGrow @UnknownShrink @UnknownReplace} on each annotated type. + * {@code @Ungrowable @Unshrinkable @Unreplaceable} on each annotated type. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java new file mode 100644 index 000000000000..1f58bc15625f --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling replace operations such as {@code set}, {@code replaceAll}, etc. on this collection will + * throw {@link UnsupportedOperationException}. + * + *

No guarantees are made about grow or shrink operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownReplace.class) +public @interface Unreplaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java new file mode 100644 index 000000000000..1b97e46abbdf --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java @@ -0,0 +1,22 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling shrink operations such as {@code remove}, {@code clear}, etc. on this collection will + * throw {@link UnsupportedOperationException}. + * + *

No guarantees are made about grow or replace operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownShrink.class) +public @interface Unshrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java deleted file mode 100644 index ab6a7dd1718f..000000000000 --- a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.checkerframework.dataflow.qual; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.checkerframework.framework.qual.JavaExpression; - -/** - * A method annotated with the declaration annotation {@code @SideEffectsOnly("A", "B")} changes the - * value of at most the expressions A and B. All other expressions have the same value before and - * after a call to the method. - * - * @checker_framework.manual #type-refinement-purity Specifying side effects - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) -public @interface SideEffectsOnly { - /** - * An upper bound on the expressions that this method might change the value of. - * - * @return the Java expressions that the annotated method might side-effect - * @checker_framework.manual #java-expressions-as-arguments Syntax of Java expressions - */ - @JavaExpression - public String[] value(); -} diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java b/src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java rename to src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java index 329ea505d64e..4eca89c86484 100644 --- a/src/java.base/share/classes/org/checkerframework/dataflow/qual/DoesNotUnrefineReceiver.java +++ b/src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java @@ -1,4 +1,4 @@ -package org.checkerframework.dataflow.qual; +package org.checkerframework.framework.qual; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; From 7bf97d8a4f7dabb21b5495a9de9e30ad924b10e6 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 22 Apr 2026 23:12:35 -0700 Subject: [PATCH 061/119] spot that list.java's iterator is not annotated as unknown. --- src/java.base/share/classes/java/util/List.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 7c7e1df2c2af..69bc34830f43 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -217,7 +217,7 @@ public interface List extends SequencedCollection { * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); + @PolyGrowShrink @UnknownModifiability @PolyNonEmpty Iterator iterator(@PolyGrowShrink @UnknownModifiability @PolyNonEmpty List this); /** * Returns an array containing all of the elements in this list in proper From b176554e8d174b8504dcfbd501fcf016f616eb3c Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 23 Apr 2026 00:28:55 -0700 Subject: [PATCH 062/119] annotate iteratorPreserveRemove for the test. TODO: need to annotate rest of the files. --- src/java.base/share/classes/java/util/ArrayList.java | 9 +++++---- src/java.base/share/classes/java/util/Map.java | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index e9fe34602084..829e7c63a7f4 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -182,7 +183,7 @@ public class ArrayList extends AbstractList * is negative */ @SideEffectFree - public @Modifiable ArrayList(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPreserveRemove ArrayList(@NonNegative int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { @@ -197,7 +198,7 @@ public class ArrayList extends AbstractList * Constructs an empty list with an initial capacity of ten. */ @SideEffectFree - public @Modifiable ArrayList() { + public @Modifiable @IteratorPreserveRemove ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } @@ -210,7 +211,7 @@ public class ArrayList extends AbstractList * @throws NullPointerException if the specified collection is null */ @SideEffectFree - public @Modifiable @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { @@ -384,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public @Modifiable Object clone(@GuardSatisfied ArrayList this) { + public @Modifiable @IteratorPreserveRemove clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 9efe1f486962..781c02862ed6 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -403,6 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** From d65f3f3ddbc97ec464e84545245e544df5634560 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 26 Apr 2026 16:09:01 -0700 Subject: [PATCH 063/119] annotate modifiable collections as @IteratorPreserveRemove --- .../share/classes/java/util/ArrayDeque.java | 9 +++--- .../share/classes/java/util/Collections.java | 3 +- .../share/classes/java/util/EnumSet.java | 29 ++++++++++--------- .../share/classes/java/util/HashSet.java | 13 +++++---- .../classes/java/util/LinkedHashSet.java | 9 +++--- .../share/classes/java/util/LinkedList.java | 7 +++-- .../classes/java/util/PriorityQueue.java | 15 +++++----- .../share/classes/java/util/Stack.java | 3 +- .../share/classes/java/util/TreeSet.java | 13 +++++---- .../share/classes/java/util/Vector.java | 11 +++---- .../util/concurrent/ArrayBlockingQueue.java | 7 +++-- .../concurrent/ConcurrentLinkedDeque.java | 5 ++-- .../concurrent/ConcurrentLinkedQueue.java | 5 ++-- .../concurrent/ConcurrentSkipListSet.java | 13 +++++---- .../java/util/concurrent/DelayQueue.java | 5 ++-- .../util/concurrent/LinkedBlockingDeque.java | 7 +++-- .../util/concurrent/LinkedBlockingQueue.java | 7 +++-- .../util/concurrent/LinkedTransferQueue.java | 5 ++-- .../concurrent/PriorityBlockingQueue.java | 9 +++--- 19 files changed, 97 insertions(+), 78 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 2974f1335515..616554b6e772 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -202,7 +203,7 @@ private int newCapacity(int needed, int jump) { * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */ - public @Modifiable ArrayDeque() { + public @Modifiable @IteratorPreserveRemove ArrayDeque() { elements = new Object[16 + 1]; } @@ -212,7 +213,7 @@ private int newCapacity(int needed, int jump) { * * @param numElements lower bound on initial capacity of the deque */ - public @Modifiable ArrayDeque(@NonNegative int numElements) { + public @Modifiable @IteratorPreserveRemove ArrayDeque(@NonNegative int numElements) { elements = new Object[(numElements < 1) ? 1 : (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : @@ -229,7 +230,7 @@ private int newCapacity(int needed, int jump) { * @param c the collection whose elements are to be placed into the deque * @throws NullPointerException if the specified collection is null */ - public @Modifiable @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { this(c.size()); copyElements(c); } @@ -1213,7 +1214,7 @@ private T[] toArray(Class klazz) { * @return a copy of this deque */ @SideEffectFree - public @Modifiable ArrayDeque clone(@GuardSatisfied ArrayDeque this) { + public @Modifiable @IteratorPreserveRemove ArrayDeque clone(@GuardSatisfied ArrayDeque this) { try { @SuppressWarnings("unchecked") ArrayDeque result = (ArrayDeque) super.clone(); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 59a382201b91..099fee1f16b8 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -6046,7 +6047,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) { * @see Enumeration * @see ArrayList */ - public static @Modifiable ArrayList list(Enumeration e) { + public static @Modifiable @IteratorPreserveRemove ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index 24ea615d8451..761acfa910e4 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -103,7 +104,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ final transient Enum[] universe; - @Modifiable EnumSet(ClasselementType, Enum[] universe) { + @Modifiable @IteratorPreserveRemove EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } @@ -117,7 +118,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An empty enum set of the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable EnumSet noneOf(Class elementType) { + public static > @Modifiable @IteratorPreserveRemove EnumSet noneOf(Class elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); @@ -138,7 +139,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An enum set containing all the elements in the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable EnumSet allOf(Class elementType) { + public static > @Modifiable @IteratorPreserveRemove EnumSet allOf(Class elementType) { EnumSet result = noneOf(elementType); result.addAll(); return result; @@ -160,7 +161,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return A copy of the specified enum set. * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable EnumSet copyOf(EnumSet s) { + public static > @Modifiable @IteratorPreserveRemove EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -178,7 +179,7 @@ public abstract sealed class EnumSet> extends AbstractSet * {@code EnumSet} instance and contains no elements * @throws NullPointerException if {@code c} is null */ - public static > @Modifiable EnumSet copyOf(Collection c) { + public static > @Modifiable @IteratorPreserveRemove EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); } else { @@ -203,7 +204,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return The complement of the specified set in this set * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable EnumSet complementOf(EnumSet s) { + public static > @Modifiable @IteratorPreserveRemove EnumSet complementOf(EnumSet s) { EnumSet result = copyOf(s); result.complement(); return result; @@ -223,7 +224,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code e} is null * @return an enum set initially containing the specified element */ - public static > @Modifiable EnumSet of(E e) { + public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); return result; @@ -244,7 +245,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable EnumSet of(E e1, E e2) { + public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -267,7 +268,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable EnumSet of(E e1, E e2, E e3) { + public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -292,7 +293,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable EnumSet of(E e1, E e2, E e3, E e4) { + public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -319,7 +320,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable EnumSet of(E e1, E e2, E e3, E e4, + public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2, E e3, E e4, E e5) { EnumSet result = noneOf(e1.getDeclaringClass()); @@ -346,7 +347,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SafeVarargs - public static > @Modifiable EnumSet of(E first, E... rest) { + public static > @Modifiable @IteratorPreserveRemove EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) @@ -368,7 +369,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ - public static > @Modifiable EnumSet range(E from, E to) { + public static > @Modifiable @IteratorPreserveRemove EnumSet range(E from, E to) { if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to); EnumSet result = noneOf(from.getDeclaringClass()); @@ -390,7 +391,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SuppressWarnings("unchecked") @DoesNotUnrefineReceiver("modifiability") - public @Modifiable EnumSet clone() { + public @Modifiable @IteratorPreserveRemove EnumSet clone() { try { return (EnumSet) super.clone(); } catch(CloneNotSupportedException e) { diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 41244751b32c..804349d0145a 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -125,7 +126,7 @@ public class HashSet * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @Modifiable HashSet() { + public @Modifiable @IteratorPreserveRemove HashSet() { map = new HashMap<>(); } @@ -138,7 +139,7 @@ public class HashSet * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -156,7 +157,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPreserveRemove HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -172,7 +173,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable HashSet(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPreserveRemove HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -189,7 +190,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @Modifiable HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable @IteratorPreserveRemove HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } @@ -293,7 +294,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable Object clone(@GuardSatisfied HashSet this) { + public @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied HashSet this) { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 285bff113405..a219082e353c 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; @@ -153,7 +154,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable LinkedHashSet(int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPreserveRemove LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } @@ -169,7 +170,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable LinkedHashSet(int initialCapacity) { + public @Modifiable @IteratorPreserveRemove LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } @@ -177,7 +178,7 @@ public class LinkedHashSet * Constructs a new, empty linked hash set with the default initial * capacity (16) and load factor (0.75). */ - public @Modifiable LinkedHashSet() { + public @Modifiable @IteratorPreserveRemove LinkedHashSet() { super(16, .75f, true); } @@ -191,7 +192,7 @@ public class LinkedHashSet * this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable LinkedHashSet(Collection c) { + public @Modifiable @IteratorPreserveRemove LinkedHashSet(Collection c) { super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true); addAll(c); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index a45acc91c49a..7ba240f48d4d 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -143,7 +144,7 @@ void dataStructureInvariants() { /** * Constructs an empty list. */ - public @Modifiable LinkedList() { + public @Modifiable @IteratorPreserveRemove LinkedList() { } /** @@ -154,7 +155,7 @@ void dataStructureInvariants() { * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ - public @Modifiable @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -1112,7 +1113,7 @@ private LinkedList superClone() { * @return a shallow copy of this {@code LinkedList} instance */ @SideEffectFree - public @Modifiable Object clone(@GuardSatisfied LinkedList this) { + public @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied LinkedList this) { LinkedList clone = superClone(); // Put clone into "virgin" state diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 02625197edd7..d84639887ea5 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -151,7 +152,7 @@ public class PriorityQueue extends AbstractQueue * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. */ - public @Modifiable PriorityQueue() { + public @Modifiable @IteratorPreserveRemove PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -164,7 +165,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable PriorityQueue(@Positive int initialCapacity) { + public @Modifiable @IteratorPreserveRemove PriorityQueue(@Positive int initialCapacity) { this(initialCapacity, null); } @@ -177,7 +178,7 @@ public class PriorityQueue extends AbstractQueue * natural ordering} of the elements will be used. * @since 1.8 */ - public @Modifiable PriorityQueue(Comparator comparator) { + public @Modifiable @IteratorPreserveRemove PriorityQueue(Comparator comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); } @@ -192,7 +193,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 */ - public @Modifiable PriorityQueue(@Positive int initialCapacity, + public @Modifiable @IteratorPreserveRemove PriorityQueue(@Positive int initialCapacity, Comparator comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility @@ -218,7 +219,7 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { if (c instanceof SortedSet) { SortedSet ss = (SortedSet) c; this.comparator = (Comparator) ss.comparator(); @@ -249,7 +250,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified priority queue or any * of its elements are null */ - public @Modifiable PriorityQueue(PriorityQueue c) { + public @Modifiable @IteratorPreserveRemove PriorityQueue(PriorityQueue c) { this.comparator = (Comparator) c.comparator(); initFromPriorityQueue(c); } @@ -267,7 +268,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable PriorityQueue(SortedSet c) { + public @Modifiable @IteratorPreserveRemove PriorityQueue(SortedSet c) { this.comparator = (Comparator) c.comparator(); initElementsFromCollection(c); } diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index cb8f7bc2ba34..940b998423cb 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -66,7 +67,7 @@ public class Stack extends Vector { /** * Creates an empty Stack. */ - public @Modifiable Stack() { + public @Modifiable @IteratorPreserveRemove Stack() { } /** diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 0ac28bf313b3..800004a81ea6 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -130,7 +131,7 @@ public class TreeSet extends AbstractSet /** * Constructs a set backed by the specified navigable map. */ - @Modifiable TreeSet(NavigableMap m) { + @Modifiable @IteratorPreserveRemove TreeSet(NavigableMap m) { this.m = m; } @@ -147,7 +148,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable TreeSet() { + public @Modifiable @IteratorPreserveRemove TreeSet() { this(new TreeMap<>()); } @@ -164,7 +165,7 @@ public class TreeSet extends AbstractSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable TreeSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPreserveRemove TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -182,7 +183,7 @@ public class TreeSet extends AbstractSet * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -194,7 +195,7 @@ public class TreeSet extends AbstractSet * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -552,7 +553,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable Object clone(@GuardSatisfied TreeSet this) { + public @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 35c7c7f61bd9..fa37254351e2 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -166,7 +167,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable Vector(@NonNegative int initialCapacity, int capacityIncrement) { + public @Modifiable @IteratorPreserveRemove Vector(@NonNegative int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ @@ -183,7 +184,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable Vector(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPreserveRemove Vector(@NonNegative int initialCapacity) { this(initialCapacity, 0); } @@ -192,7 +193,7 @@ public class Vector * has size {@code 10} and its standard capacity increment is * zero. */ - public @Modifiable Vector() { + public @Modifiable @IteratorPreserveRemove Vector() { this(10); } @@ -206,7 +207,7 @@ public class Vector * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public @Modifiable @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreserveRemove @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); elementCount = a.length; if (c.getClass() == ArrayList.class) { @@ -711,7 +712,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @return a clone of this vector */ @SideEffectFree - public synchronized @Modifiable Object clone(@GuardSatisfied Vector this) { + public synchronized @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied Vector this) { try { @SuppressWarnings("unchecked") Vector v = (Vector) super.clone(); 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 6d1e38280473..bc10c9fd5533 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -275,7 +276,7 @@ void removeAt(final int removeIndex) { * @param capacity the capacity of this queue * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable ArrayBlockingQueue(int capacity) { + public @Modifiable @IteratorPreserveRemove ArrayBlockingQueue(int capacity) { this(capacity, false); } @@ -289,7 +290,7 @@ void removeAt(final int removeIndex) { * if {@code false} the access order is unspecified. * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable ArrayBlockingQueue(int capacity, boolean fair) { + public @Modifiable @IteratorPreserveRemove ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; @@ -314,7 +315,7 @@ void removeAt(final int removeIndex) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable ArrayBlockingQueue(int capacity, boolean fair, + public @Modifiable @IteratorPreserveRemove ArrayBlockingQueue(int capacity, boolean fair, Collection c) { this(capacity, fair); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 7fce4bc51a8c..f65e9560dc63 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -792,7 +793,7 @@ private E screenNullResult(@NonNull E v) { /** * Constructs an empty deque. */ - public @Modifiable ConcurrentLinkedDeque() { + public @Modifiable @IteratorPreserveRemove ConcurrentLinkedDeque() { head = tail = new Node(); } @@ -805,7 +806,7 @@ private E screenNullResult(@NonNull E v) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable ConcurrentLinkedDeque(Collection c) { + public @Modifiable @IteratorPreserveRemove ConcurrentLinkedDeque(Collection c) { // Copy c into a private chain of Nodes Node h = null, t = null; for (E e : c) { diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 1e289de70597..4b5d59529fa1 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -264,7 +265,7 @@ boolean casItem(E cmp, E val) { /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public @Modifiable ConcurrentLinkedQueue() { + public @Modifiable @IteratorPreserveRemove ConcurrentLinkedQueue() { head = tail = new Node(); } @@ -277,7 +278,7 @@ boolean casItem(E cmp, E val) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable ConcurrentLinkedQueue(Collection c) { + public @Modifiable @IteratorPreserveRemove ConcurrentLinkedQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index a458a08cdcd2..90eadcce94c4 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -131,7 +132,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable ConcurrentSkipListSet() { + public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -143,7 +144,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -158,7 +159,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable ConcurrentSkipListSet(Collection c) { + public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -171,7 +172,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable ConcurrentSkipListSet(SortedSet s) { + public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -179,7 +180,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -190,7 +191,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable ConcurrentSkipListSet clone() { + public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 6369edd3dc28..0ce07e873618 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,6 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -153,7 +154,7 @@ public class DelayQueue extends AbstractQueue /** * Creates a new {@code DelayQueue} that is initially empty. */ - public @Modifiable DelayQueue() {} + public @Modifiable @IteratorPreserveRemove DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -163,7 +164,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable DelayQueue(Collection c) { + public @Modifiable @IteratorPreserveRemove DelayQueue(Collection c) { this.addAll(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 2e4550f519d6..6291ac7f502b 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -193,7 +194,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable LinkedBlockingDeque() { + public @Modifiable @IteratorPreserveRemove LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -203,7 +204,7 @@ static final class Node { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public @Modifiable LinkedBlockingDeque(int capacity) { + public @Modifiable @IteratorPreserveRemove LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -218,7 +219,7 @@ static final class Node { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable LinkedBlockingDeque(Collection c) { + public @Modifiable @IteratorPreserveRemove LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } 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 8bde84325e0a..1c12b86d4a96 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -263,7 +264,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable LinkedBlockingQueue() { + public @Modifiable @IteratorPreserveRemove LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -274,7 +275,7 @@ void fullyUnlock() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public @Modifiable LinkedBlockingQueue(int capacity) { + public @Modifiable @IteratorPreserveRemove LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -290,7 +291,7 @@ void fullyUnlock() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable LinkedBlockingQueue(Collection c) { + public @Modifiable @IteratorPreserveRemove LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 9304865e8a33..4c33b12262bd 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1178,7 +1179,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public @Modifiable LinkedTransferQueue() { + public @Modifiable @IteratorPreserveRemove LinkedTransferQueue() { head = tail = new Node(); } @@ -1191,7 +1192,7 @@ else if (s == n) // stale * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable LinkedTransferQueue(Collection c) { + public @Modifiable @IteratorPreserveRemove LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(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 d5a76c5bec0b..69604ad38ec6 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,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -209,7 +210,7 @@ public class PriorityBlockingQueue extends AbstractQueue * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable PriorityBlockingQueue() { + public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -222,7 +223,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable PriorityBlockingQueue(int initialCapacity) { + public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -238,7 +239,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable PriorityBlockingQueue(int initialCapacity, + public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -262,7 +263,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable PriorityBlockingQueue(Collection c) { + public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { From 046a3c5418e5a2871749e5c1ddc588d35a9ce456 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 26 Apr 2026 18:08:02 -0700 Subject: [PATCH 064/119] annotated @IteratorPreserveRemove on maps. --- .../share/classes/java/util/AbstractMap.java | 4 ++++ .../share/classes/java/util/Collections.java | 12 ++++++++++++ src/java.base/share/classes/java/util/EnumMap.java | 4 ++++ src/java.base/share/classes/java/util/HashMap.java | 4 ++++ src/java.base/share/classes/java/util/Hashtable.java | 4 ++++ .../share/classes/java/util/IdentityHashMap.java | 4 ++++ .../share/classes/java/util/LinkedHashMap.java | 7 +++++++ src/java.base/share/classes/java/util/Map.java | 4 +++- .../share/classes/java/util/NavigableMap.java | 3 +++ .../share/classes/java/util/Properties.java | 4 ++++ .../classes/java/util/ReverseOrderSortedMapView.java | 5 +++++ src/java.base/share/classes/java/util/SortedMap.java | 4 ++++ src/java.base/share/classes/java/util/TreeMap.java | 11 +++++++++++ .../share/classes/java/util/WeakHashMap.java | 4 ++++ .../java/util/concurrent/ConcurrentHashMap.java | 5 +++++ .../java/util/concurrent/ConcurrentNavigableMap.java | 4 ++++ .../java/util/concurrent/ConcurrentSkipListMap.java | 11 +++++++++++ 17 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index ac29a3ab4ae9..abbd7b2922a7 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -390,6 +391,7 @@ public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { * method will not all return the same set. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { @@ -460,6 +462,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { @@ -513,6 +516,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree + @IteratorPreserveRemove public abstract @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 099fee1f16b8..78e9f95add2d 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -3087,6 +3087,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; + @IteratorPreserveRemove public Set keySet() { synchronized (mutex) { if (keySet==null) @@ -3096,6 +3097,7 @@ public Set keySet() { } @SideEffectFree + @IteratorPreserveRemove public Set> entrySet() { synchronized (mutex) { if (entrySet==null) @@ -3104,6 +3106,7 @@ public Set> entrySet() { } } + @IteratorPreserveRemove public Collection values() { synchronized (mutex) { if (values==null) @@ -3394,11 +3397,13 @@ public NavigableMap descendingMap() { } } + @IteratorPreserveRemove public NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree + @IteratorPreserveRemove public NavigableSet navigableKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); @@ -3406,6 +3411,7 @@ public NavigableSet navigableKeySet() { } @SideEffectFree + @IteratorPreserveRemove public NavigableSet descendingKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); @@ -4185,7 +4191,9 @@ private String badValueMsg(Object value) { public V get(Object key) { return m.get(key); } public V remove(Object key) { return m.remove(key); } public void clear() { m.clear(); } + @IteratorPreserveRemove public Set keySet() { return m.keySet(); } + @IteratorPreserveRemove public Collection values() { return m.values(); } public boolean equals(Object o) { return o == this || m.equals(o); } public int hashCode() { return m.hashCode(); } @@ -4221,6 +4229,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree + @IteratorPreserveRemove public Set> entrySet() { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); @@ -4713,16 +4722,19 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } + @IteratorPreserveRemove public NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree + @IteratorPreserveRemove public NavigableSet navigableKeySet() { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree + @IteratorPreserveRemove public NavigableSet descendingKeySet() { return checkedNavigableSet(nm.descendingKeySet(), keyType); } diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 1f12bbf8bc5c..f1cc403c2afe 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -412,6 +413,7 @@ public void clear(@Shrinkable EnumMap this) { * * @return a set view of the keys contained in this enum map */ + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { Set ks = keySet; if (ks == null) { @@ -455,6 +457,7 @@ public void clear(@Shrinkable KeySet this) { * * @return a collection view of the values contained in this map */ + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { Collection vs = values; if (vs == null) { @@ -505,6 +508,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 915416c8ec96..c846de0f75c8 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -952,6 +953,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { @@ -1090,6 +1092,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { @@ -1156,6 +1159,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 0826e420ef32..e3df68657e66 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -702,6 +703,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); @@ -749,6 +751,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); @@ -837,6 +840,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 9ab5b1b4720d..47129249851e 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1034,6 +1035,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { @@ -1150,6 +1152,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { @@ -1266,6 +1269,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 50a4a6df451f..9aae22805d9d 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -654,6 +655,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { return sequencedKeySet(); } @@ -814,6 +816,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { return sequencedValues(); } @@ -929,6 +932,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -1228,14 +1232,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } + @IteratorPreserveRemove public Set keySet() { return base.sequencedKeySet().reversed(); } + @IteratorPreserveRemove public Collection values() { return base.sequencedValues().reversed(); } + @IteratorPreserveRemove public Set> entrySet() { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 781c02862ed6..05ed47b066be 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -404,7 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreserveRemove @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** @@ -423,6 +423,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** @@ -442,6 +443,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 183924b1e891..634b7143a113 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,6 +36,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -312,6 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); /** @@ -329,6 +331,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); /** diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 4ac828027799..44c546a6ef1a 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -1394,17 +1395,20 @@ public synchronized String toString() { } @Override + @IteratorPreserveRemove public Set<@KeyFor("this") Object> keySet() { return Collections.synchronizedSet(map.keySet(), this); } @Override + @IteratorPreserveRemove public Collection values() { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree + @IteratorPreserveRemove public Set> entrySet() { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 8e750326b3c7..a685669ef57a 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -25,6 +25,7 @@ package java.util; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.dataflow.qual.Pure; /** @@ -97,6 +98,7 @@ public int size() { return base.size(); } + @IteratorPreserveRemove public Set keySet() { return new AbstractSet<>() { // inherit add(), which throws UOE @@ -108,6 +110,7 @@ public Set keySet() { }; } + @IteratorPreserveRemove public Collection values() { return new AbstractCollection<>() { // inherit add(), which throws UOE @@ -119,6 +122,7 @@ public Collection values() { }; } + @IteratorPreserveRemove public Set> entrySet() { return new AbstractSet<>() { // inherit add(), which throws UOE @@ -394,6 +398,7 @@ public String toString() { return ReverseOrderSortedMapView.toString(this, entryIterator()); } + @IteratorPreserveRemove public Set> entrySet() { return new AbstractSet<>() { public Iterator> iterator() { diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 5f34c3171645..57c90ba45952 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -264,6 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); /** @@ -285,6 +287,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); /** @@ -306,6 +309,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 5b0e549c2e23..938635a35c7d 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1189,6 +1190,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @DoesNotUnrefineReceiver("modifiability") + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1197,6 +1199,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); @@ -1206,6 +1209,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1231,6 +1235,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { @@ -1263,6 +1268,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); @@ -2053,17 +2059,20 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree + @IteratorPreserveRemove public final NavigableSet navigableKeySet() { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } + @IteratorPreserveRemove public final Set keySet() { return navigableKeySet(); } @SideEffectFree + @IteratorPreserveRemove public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } @@ -2390,6 +2399,7 @@ public Iterator> iterator() { } @SideEffectFree + @IteratorPreserveRemove public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); @@ -2483,6 +2493,7 @@ public Iterator> iterator() { } @SideEffectFree + @IteratorPreserveRemove public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index b36dff80f000..d3119f5c9850 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -921,6 +922,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { @@ -982,6 +984,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { @@ -1034,6 +1037,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 503622e6f060..19b02cc3d875 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1279,6 +1280,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree + @IteratorPreserveRemove public KeySetView<@KeyFor({"this"}) K,V> keySet() { KeySetView ks; if ((ks = keySet) != null) return ks; @@ -1304,6 +1306,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; @@ -1328,6 +1331,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; @@ -2283,6 +2287,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @return the set view * @throws NullPointerException if the mappedValue is null */ + @IteratorPreserveRemove public KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index cdcd39810ac5..47a4cd6a338e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -36,6 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -146,6 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); /** @@ -166,6 +168,7 @@ public interface ConcurrentNavigableMap * * @return a navigable set view of the keys in this map */ + @IteratorPreserveRemove @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); /** @@ -185,5 +188,6 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree + @IteratorPreserveRemove @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 927b0c2a45f0..187dd76a4495 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -37,6 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1649,6 +1650,7 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ + @IteratorPreserveRemove public @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1656,6 +1658,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1681,6 +1684,7 @@ else if (doRemove(key, v) != null) *

The view's iterators and spliterators are * weakly consistent. */ + @IteratorPreserveRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; @@ -1715,6 +1719,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; @@ -1730,6 +1735,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree + @IteratorPreserveRemove public @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3010,6 +3016,7 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ + @IteratorPreserveRemove public NavigableSet keySet() { KeySet ks; if ((ks = keySetView) != null) return ks; @@ -3017,12 +3024,14 @@ public NavigableSet keySet() { } @SideEffectFree + @IteratorPreserveRemove public NavigableSet navigableKeySet() { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } + @IteratorPreserveRemove public Collection values() { Values vs; if ((vs = valuesView) != null) return vs; @@ -3030,6 +3039,7 @@ public Collection values() { } @SideEffectFree + @IteratorPreserveRemove public Set> entrySet() { EntrySet es; if ((es = entrySetView) != null) return es; @@ -3037,6 +3047,7 @@ public Set> entrySet() { } @SideEffectFree + @IteratorPreserveRemove public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } From dea0a375ecfbf3c29afd88c66bd546f68d44f73e Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 29 Apr 2026 12:51:00 -0700 Subject: [PATCH 065/119] changed annoations to IteratorPreservesRemove --- .../share/classes/java/util/AbstractMap.java | 8 ++--- .../share/classes/java/util/ArrayDeque.java | 10 +++---- .../share/classes/java/util/ArrayList.java | 10 +++---- .../share/classes/java/util/Collections.java | 28 ++++++++--------- .../share/classes/java/util/EnumMap.java | 8 ++--- .../share/classes/java/util/EnumSet.java | 30 +++++++++---------- .../share/classes/java/util/HashMap.java | 8 ++--- .../share/classes/java/util/HashSet.java | 14 ++++----- .../share/classes/java/util/Hashtable.java | 8 ++--- .../classes/java/util/IdentityHashMap.java | 8 ++--- .../classes/java/util/LinkedHashMap.java | 14 ++++----- .../classes/java/util/LinkedHashSet.java | 10 +++---- .../share/classes/java/util/LinkedList.java | 8 ++--- .../share/classes/java/util/Map.java | 8 ++--- .../share/classes/java/util/NavigableMap.java | 6 ++-- .../classes/java/util/PriorityQueue.java | 16 +++++----- .../share/classes/java/util/Properties.java | 8 ++--- .../java/util/ReverseOrderSortedMapView.java | 10 +++---- .../share/classes/java/util/SortedMap.java | 8 ++--- .../share/classes/java/util/Stack.java | 4 +-- .../share/classes/java/util/TreeMap.java | 22 +++++++------- .../share/classes/java/util/TreeSet.java | 14 ++++----- .../share/classes/java/util/Vector.java | 12 ++++---- .../share/classes/java/util/WeakHashMap.java | 8 ++--- .../util/concurrent/ArrayBlockingQueue.java | 8 ++--- .../util/concurrent/ConcurrentHashMap.java | 10 +++---- .../concurrent/ConcurrentLinkedDeque.java | 6 ++-- .../concurrent/ConcurrentLinkedQueue.java | 6 ++-- .../concurrent/ConcurrentNavigableMap.java | 8 ++--- .../concurrent/ConcurrentSkipListMap.java | 22 +++++++------- .../concurrent/ConcurrentSkipListSet.java | 14 ++++----- .../java/util/concurrent/DelayQueue.java | 6 ++-- .../util/concurrent/LinkedBlockingDeque.java | 8 ++--- .../util/concurrent/LinkedBlockingQueue.java | 8 ++--- .../util/concurrent/LinkedTransferQueue.java | 6 ++-- .../concurrent/PriorityBlockingQueue.java | 10 +++---- 36 files changed, 196 insertions(+), 196 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index abbd7b2922a7..8ff874821963 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -391,7 +391,7 @@ public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { * method will not all return the same set. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { @@ -462,7 +462,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { @@ -516,7 +516,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public abstract @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 616554b6e772..8ad2bb07f65c 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -203,7 +203,7 @@ private int newCapacity(int needed, int jump) { * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */ - public @Modifiable @IteratorPreserveRemove ArrayDeque() { + public @Modifiable @IteratorPreservesRemove ArrayDeque() { elements = new Object[16 + 1]; } @@ -213,7 +213,7 @@ private int newCapacity(int needed, int jump) { * * @param numElements lower bound on initial capacity of the deque */ - public @Modifiable @IteratorPreserveRemove ArrayDeque(@NonNegative int numElements) { + public @Modifiable @IteratorPreservesRemove ArrayDeque(@NonNegative int numElements) { elements = new Object[(numElements < 1) ? 1 : (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : @@ -230,7 +230,7 @@ private int newCapacity(int needed, int jump) { * @param c the collection whose elements are to be placed into the deque * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { this(c.size()); copyElements(c); } @@ -1214,7 +1214,7 @@ private T[] toArray(Class klazz) { * @return a copy of this deque */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove ArrayDeque clone(@GuardSatisfied ArrayDeque this) { + public @Modifiable @IteratorPreservesRemove ArrayDeque clone(@GuardSatisfied ArrayDeque this) { try { @SuppressWarnings("unchecked") ArrayDeque result = (ArrayDeque) super.clone(); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 829e7c63a7f4..b46df72d0b8e 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -183,7 +183,7 @@ public class ArrayList extends AbstractList * is negative */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove ArrayList(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPreservesRemove ArrayList(@NonNegative int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { @@ -198,7 +198,7 @@ public class ArrayList extends AbstractList * Constructs an empty list with an initial capacity of ten. */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove ArrayList() { + public @Modifiable @IteratorPreservesRemove ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } @@ -211,7 +211,7 @@ public class ArrayList extends AbstractList * @throws NullPointerException if the specified collection is null */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { @@ -385,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove clone(@GuardSatisfied ArrayList this) { + public @Modifiable @IteratorPreservesRemove clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 78e9f95add2d..b4d7af5e642f 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -3087,7 +3087,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - @IteratorPreserveRemove + @IteratorPreservesRemove public Set keySet() { synchronized (mutex) { if (keySet==null) @@ -3097,7 +3097,7 @@ public Set keySet() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { synchronized (mutex) { if (entrySet==null) @@ -3106,7 +3106,7 @@ public Set> entrySet() { } } - @IteratorPreserveRemove + @IteratorPreservesRemove public Collection values() { synchronized (mutex) { if (values==null) @@ -3397,13 +3397,13 @@ public NavigableMap descendingMap() { } } - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet navigableKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); @@ -3411,7 +3411,7 @@ public NavigableSet navigableKeySet() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet descendingKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); @@ -4191,9 +4191,9 @@ private String badValueMsg(Object value) { public V get(Object key) { return m.get(key); } public V remove(Object key) { return m.remove(key); } public void clear() { m.clear(); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Set keySet() { return m.keySet(); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Collection values() { return m.values(); } public boolean equals(Object o) { return o == this || m.equals(o); } public int hashCode() { return m.hashCode(); } @@ -4229,7 +4229,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); @@ -4722,19 +4722,19 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet navigableKeySet() { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet descendingKeySet() { return checkedNavigableSet(nm.descendingKeySet(), keyType); } @@ -6059,7 +6059,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) { * @see Enumeration * @see ArrayList */ - public static @Modifiable @IteratorPreserveRemove ArrayList list(Enumeration e) { + public static @Modifiable @IteratorPreservesRemove ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index f1cc403c2afe..18776e7b887b 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -413,7 +413,7 @@ public void clear(@Shrinkable EnumMap this) { * * @return a set view of the keys contained in this enum map */ - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { Set ks = keySet; if (ks == null) { @@ -457,7 +457,7 @@ public void clear(@Shrinkable KeySet this) { * * @return a collection view of the values contained in this map */ - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { Collection vs = values; if (vs == null) { @@ -508,7 +508,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index 761acfa910e4..a2f1e91bff50 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -104,7 +104,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ final transient Enum[] universe; - @Modifiable @IteratorPreserveRemove EnumSet(ClasselementType, Enum[] universe) { + @Modifiable @IteratorPreservesRemove EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } @@ -118,7 +118,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An empty enum set of the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPreserveRemove EnumSet noneOf(Class elementType) { + public static > @Modifiable @IteratorPreservesRemove EnumSet noneOf(Class elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); @@ -139,7 +139,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An enum set containing all the elements in the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPreserveRemove EnumSet allOf(Class elementType) { + public static > @Modifiable @IteratorPreservesRemove EnumSet allOf(Class elementType) { EnumSet result = noneOf(elementType); result.addAll(); return result; @@ -161,7 +161,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return A copy of the specified enum set. * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable @IteratorPreserveRemove EnumSet copyOf(EnumSet s) { + public static > @Modifiable @IteratorPreservesRemove EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -179,7 +179,7 @@ public abstract sealed class EnumSet> extends AbstractSet * {@code EnumSet} instance and contains no elements * @throws NullPointerException if {@code c} is null */ - public static > @Modifiable @IteratorPreserveRemove EnumSet copyOf(Collection c) { + public static > @Modifiable @IteratorPreservesRemove EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); } else { @@ -204,7 +204,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return The complement of the specified set in this set * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable @IteratorPreserveRemove EnumSet complementOf(EnumSet s) { + public static > @Modifiable @IteratorPreservesRemove EnumSet complementOf(EnumSet s) { EnumSet result = copyOf(s); result.complement(); return result; @@ -224,7 +224,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code e} is null * @return an enum set initially containing the specified element */ - public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e) { + public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); return result; @@ -245,7 +245,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2) { + public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -268,7 +268,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2, E e3) { + public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -293,7 +293,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2, E e3, E e4) { + public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -320,7 +320,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreserveRemove EnumSet of(E e1, E e2, E e3, E e4, + public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2, E e3, E e4, E e5) { EnumSet result = noneOf(e1.getDeclaringClass()); @@ -347,7 +347,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SafeVarargs - public static > @Modifiable @IteratorPreserveRemove EnumSet of(E first, E... rest) { + public static > @Modifiable @IteratorPreservesRemove EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) @@ -369,7 +369,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ - public static > @Modifiable @IteratorPreserveRemove EnumSet range(E from, E to) { + public static > @Modifiable @IteratorPreservesRemove EnumSet range(E from, E to) { if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to); EnumSet result = noneOf(from.getDeclaringClass()); @@ -391,7 +391,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SuppressWarnings("unchecked") @DoesNotUnrefineReceiver("modifiability") - public @Modifiable @IteratorPreserveRemove EnumSet clone() { + public @Modifiable @IteratorPreservesRemove EnumSet clone() { try { return (EnumSet) super.clone(); } catch(CloneNotSupportedException e) { diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index c846de0f75c8..3cc84e08d357 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -953,7 +953,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { @@ -1092,7 +1092,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { @@ -1159,7 +1159,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 804349d0145a..c0c2351a3ea9 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -126,7 +126,7 @@ public class HashSet * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPreserveRemove HashSet() { + public @Modifiable @IteratorPreservesRemove HashSet() { map = new HashMap<>(); } @@ -139,7 +139,7 @@ public class HashSet * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -157,7 +157,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPreserveRemove HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPreservesRemove HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -173,7 +173,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPreserveRemove HashSet(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPreservesRemove HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -190,7 +190,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @Modifiable @IteratorPreserveRemove HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable @IteratorPreservesRemove HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } @@ -294,7 +294,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied HashSet this) { + public @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied HashSet this) { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index e3df68657e66..22fe89b652b4 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -703,7 +703,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); @@ -751,7 +751,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); @@ -840,7 +840,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 47129249851e..55c482d9f6ba 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1035,7 +1035,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { @@ -1152,7 +1152,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { @@ -1269,7 +1269,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 9aae22805d9d..a40c2b422b6e 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -655,7 +655,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { return sequencedKeySet(); } @@ -816,7 +816,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { return sequencedValues(); } @@ -932,7 +932,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -1232,17 +1232,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Set keySet() { return base.sequencedKeySet().reversed(); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Collection values() { return base.sequencedValues().reversed(); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index a219082e353c..5a63bb93dac3 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; @@ -154,7 +154,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPreserveRemove LinkedHashSet(int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPreservesRemove LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } @@ -170,7 +170,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPreserveRemove LinkedHashSet(int initialCapacity) { + public @Modifiable @IteratorPreservesRemove LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } @@ -178,7 +178,7 @@ public class LinkedHashSet * Constructs a new, empty linked hash set with the default initial * capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPreserveRemove LinkedHashSet() { + public @Modifiable @IteratorPreservesRemove LinkedHashSet() { super(16, .75f, true); } @@ -192,7 +192,7 @@ public class LinkedHashSet * this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreserveRemove LinkedHashSet(Collection c) { + public @Modifiable @IteratorPreservesRemove LinkedHashSet(Collection c) { super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true); addAll(c); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index 7ba240f48d4d..3900c58d8984 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -144,7 +144,7 @@ void dataStructureInvariants() { /** * Constructs an empty list. */ - public @Modifiable @IteratorPreserveRemove LinkedList() { + public @Modifiable @IteratorPreservesRemove LinkedList() { } /** @@ -155,7 +155,7 @@ void dataStructureInvariants() { * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -1113,7 +1113,7 @@ private LinkedList superClone() { * @return a shallow copy of this {@code LinkedList} instance */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied LinkedList this) { + public @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied LinkedList this) { LinkedList clone = superClone(); // Put clone into "virgin" state diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 05ed47b066be..10cbe9518145 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -404,7 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** @@ -423,7 +423,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** @@ -443,7 +443,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 634b7143a113..ae81ad847d46 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,7 +36,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -313,7 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); /** @@ -331,7 +331,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); /** diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index d84639887ea5..7c5dd80649c1 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -152,7 +152,7 @@ public class PriorityQueue extends AbstractQueue * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPreserveRemove PriorityQueue() { + public @Modifiable @IteratorPreservesRemove PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -165,7 +165,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPreserveRemove PriorityQueue(@Positive int initialCapacity) { + public @Modifiable @IteratorPreservesRemove PriorityQueue(@Positive int initialCapacity) { this(initialCapacity, null); } @@ -178,7 +178,7 @@ public class PriorityQueue extends AbstractQueue * natural ordering} of the elements will be used. * @since 1.8 */ - public @Modifiable @IteratorPreserveRemove PriorityQueue(Comparator comparator) { + public @Modifiable @IteratorPreservesRemove PriorityQueue(Comparator comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); } @@ -193,7 +193,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 */ - public @Modifiable @IteratorPreserveRemove PriorityQueue(@Positive int initialCapacity, + public @Modifiable @IteratorPreservesRemove PriorityQueue(@Positive int initialCapacity, Comparator comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility @@ -219,7 +219,7 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { if (c instanceof SortedSet) { SortedSet ss = (SortedSet) c; this.comparator = (Comparator) ss.comparator(); @@ -250,7 +250,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified priority queue or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove PriorityQueue(PriorityQueue c) { + public @Modifiable @IteratorPreservesRemove PriorityQueue(PriorityQueue c) { this.comparator = (Comparator) c.comparator(); initFromPriorityQueue(c); } @@ -268,7 +268,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove PriorityQueue(SortedSet c) { + public @Modifiable @IteratorPreservesRemove PriorityQueue(SortedSet c) { this.comparator = (Comparator) c.comparator(); initElementsFromCollection(c); } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 44c546a6ef1a..bbbf861a973f 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -1395,20 +1395,20 @@ public synchronized String toString() { } @Override - @IteratorPreserveRemove + @IteratorPreservesRemove public Set<@KeyFor("this") Object> keySet() { return Collections.synchronizedSet(map.keySet(), this); } @Override - @IteratorPreserveRemove + @IteratorPreservesRemove public Collection values() { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index a685669ef57a..442d1b279529 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -25,7 +25,7 @@ package java.util; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.dataflow.qual.Pure; /** @@ -98,7 +98,7 @@ public int size() { return base.size(); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Set keySet() { return new AbstractSet<>() { // inherit add(), which throws UOE @@ -110,7 +110,7 @@ public Set keySet() { }; } - @IteratorPreserveRemove + @IteratorPreservesRemove public Collection values() { return new AbstractCollection<>() { // inherit add(), which throws UOE @@ -122,7 +122,7 @@ public Collection values() { }; } - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { return new AbstractSet<>() { // inherit add(), which throws UOE @@ -398,7 +398,7 @@ public String toString() { return ReverseOrderSortedMapView.toString(this, entryIterator()); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { return new AbstractSet<>() { public Iterator> iterator() { diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 57c90ba45952..c12b7899224d 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -265,7 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); /** @@ -287,7 +287,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); /** @@ -309,7 +309,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 940b998423cb..30f26e82df35 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -67,7 +67,7 @@ public class Stack extends Vector { /** * Creates an empty Stack. */ - public @Modifiable @IteratorPreserveRemove Stack() { + public @Modifiable @IteratorPreservesRemove Stack() { } /** diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 938635a35c7d..bfc0691ef3cb 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1190,7 +1190,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @DoesNotUnrefineReceiver("modifiability") - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1199,7 +1199,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); @@ -1209,7 +1209,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1235,7 +1235,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { @@ -1268,7 +1268,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); @@ -2059,20 +2059,20 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public final NavigableSet navigableKeySet() { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } - @IteratorPreserveRemove + @IteratorPreservesRemove public final Set keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } @@ -2399,7 +2399,7 @@ public Iterator> iterator() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); @@ -2493,7 +2493,7 @@ public Iterator> iterator() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 800004a81ea6..acf9d6945e74 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -131,7 +131,7 @@ public class TreeSet extends AbstractSet /** * Constructs a set backed by the specified navigable map. */ - @Modifiable @IteratorPreserveRemove TreeSet(NavigableMap m) { + @Modifiable @IteratorPreservesRemove TreeSet(NavigableMap m) { this.m = m; } @@ -148,7 +148,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable @IteratorPreserveRemove TreeSet() { + public @Modifiable @IteratorPreservesRemove TreeSet() { this(new TreeMap<>()); } @@ -165,7 +165,7 @@ public class TreeSet extends AbstractSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPreserveRemove TreeSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPreservesRemove TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -183,7 +183,7 @@ public class TreeSet extends AbstractSet * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -553,7 +553,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied TreeSet this) { + public @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index fa37254351e2..136923ca3c34 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -167,7 +167,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPreserveRemove Vector(@NonNegative int initialCapacity, int capacityIncrement) { + public @Modifiable @IteratorPreservesRemove Vector(@NonNegative int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ @@ -184,7 +184,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPreserveRemove Vector(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPreservesRemove Vector(@NonNegative int initialCapacity) { this(initialCapacity, 0); } @@ -193,7 +193,7 @@ public class Vector * has size {@code 10} and its standard capacity increment is * zero. */ - public @Modifiable @IteratorPreserveRemove Vector() { + public @Modifiable @IteratorPreservesRemove Vector() { this(10); } @@ -207,7 +207,7 @@ public class Vector * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public @Modifiable @IteratorPreserveRemove @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPreservesRemove @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); elementCount = a.length; if (c.getClass() == ArrayList.class) { @@ -712,7 +712,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @return a clone of this vector */ @SideEffectFree - public synchronized @Modifiable @IteratorPreserveRemove Object clone(@GuardSatisfied Vector this) { + public synchronized @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied Vector this) { try { @SuppressWarnings("unchecked") Vector v = (Vector) super.clone(); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index d3119f5c9850..39c48997667d 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -922,7 +922,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { @@ -984,7 +984,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { @@ -1037,7 +1037,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); 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 bc10c9fd5533..9f2f6c0b370e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -276,7 +276,7 @@ void removeAt(final int removeIndex) { * @param capacity the capacity of this queue * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPreserveRemove ArrayBlockingQueue(int capacity) { + public @Modifiable @IteratorPreservesRemove ArrayBlockingQueue(int capacity) { this(capacity, false); } @@ -290,7 +290,7 @@ void removeAt(final int removeIndex) { * if {@code false} the access order is unspecified. * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPreserveRemove ArrayBlockingQueue(int capacity, boolean fair) { + public @Modifiable @IteratorPreservesRemove ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; @@ -315,7 +315,7 @@ void removeAt(final int removeIndex) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove ArrayBlockingQueue(int capacity, boolean fair, + public @Modifiable @IteratorPreservesRemove ArrayBlockingQueue(int capacity, boolean fair, Collection c) { this(capacity, fair); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 19b02cc3d875..a7a5fd755fd5 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1280,7 +1280,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public KeySetView<@KeyFor({"this"}) K,V> keySet() { KeySetView ks; if ((ks = keySet) != null) return ks; @@ -1306,7 +1306,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; @@ -1331,7 +1331,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; @@ -2287,7 +2287,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @return the set view * @throws NullPointerException if the mappedValue is null */ - @IteratorPreserveRemove + @IteratorPreservesRemove public KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index f65e9560dc63..37494772d50f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -793,7 +793,7 @@ private E screenNullResult(@NonNull E v) { /** * Constructs an empty deque. */ - public @Modifiable @IteratorPreserveRemove ConcurrentLinkedDeque() { + public @Modifiable @IteratorPreservesRemove ConcurrentLinkedDeque() { head = tail = new Node(); } @@ -806,7 +806,7 @@ private E screenNullResult(@NonNull E v) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove ConcurrentLinkedDeque(Collection c) { + public @Modifiable @IteratorPreservesRemove ConcurrentLinkedDeque(Collection c) { // Copy c into a private chain of Nodes Node h = null, t = null; for (E e : c) { diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 4b5d59529fa1..43e6e57de2d4 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -265,7 +265,7 @@ boolean casItem(E cmp, E val) { /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public @Modifiable @IteratorPreserveRemove ConcurrentLinkedQueue() { + public @Modifiable @IteratorPreservesRemove ConcurrentLinkedQueue() { head = tail = new Node(); } @@ -278,7 +278,7 @@ boolean casItem(E cmp, E val) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove ConcurrentLinkedQueue(Collection c) { + public @Modifiable @IteratorPreservesRemove ConcurrentLinkedQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index 47a4cd6a338e..c0dbdc03365b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -147,7 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); /** @@ -168,7 +168,7 @@ public interface ConcurrentNavigableMap * * @return a navigable set view of the keys in this map */ - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); /** @@ -188,6 +188,6 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 187dd76a4495..ea3ea601d713 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1650,7 +1650,7 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1658,7 +1658,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1684,7 +1684,7 @@ else if (doRemove(key, v) != null) *

The view's iterators and spliterators are * weakly consistent. */ - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; @@ -1719,7 +1719,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; @@ -1735,7 +1735,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3016,7 +3016,7 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet keySet() { KeySet ks; if ((ks = keySetView) != null) return ks; @@ -3024,14 +3024,14 @@ public NavigableSet keySet() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet navigableKeySet() { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } - @IteratorPreserveRemove + @IteratorPreservesRemove public Collection values() { Values vs; if ((vs = valuesView) != null) return vs; @@ -3039,7 +3039,7 @@ public Collection values() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public Set> entrySet() { EntrySet es; if ((es = entrySetView) != null) return es; @@ -3047,7 +3047,7 @@ public Set> entrySet() { } @SideEffectFree - @IteratorPreserveRemove + @IteratorPreservesRemove public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 90eadcce94c4..34b92aa3558e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -132,7 +132,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet() { + public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -144,7 +144,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -159,7 +159,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(Collection c) { + public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -172,7 +172,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(SortedSet s) { + public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -180,7 +180,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -191,7 +191,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable @IteratorPreserveRemove ConcurrentSkipListSet clone() { + public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 0ce07e873618..32be820f1a5f 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -154,7 +154,7 @@ public class DelayQueue extends AbstractQueue /** * Creates a new {@code DelayQueue} that is initially empty. */ - public @Modifiable @IteratorPreserveRemove DelayQueue() {} + public @Modifiable @IteratorPreservesRemove DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -164,7 +164,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove DelayQueue(Collection c) { + public @Modifiable @IteratorPreservesRemove DelayQueue(Collection c) { this.addAll(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 6291ac7f502b..93938b94b644 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -194,7 +194,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPreserveRemove LinkedBlockingDeque() { + public @Modifiable @IteratorPreservesRemove LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -204,7 +204,7 @@ static final class Node { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public @Modifiable @IteratorPreserveRemove LinkedBlockingDeque(int capacity) { + public @Modifiable @IteratorPreservesRemove LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -219,7 +219,7 @@ static final class Node { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove LinkedBlockingDeque(Collection c) { + public @Modifiable @IteratorPreservesRemove LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } 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 1c12b86d4a96..4e9feb1b770c 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -264,7 +264,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPreserveRemove LinkedBlockingQueue() { + public @Modifiable @IteratorPreservesRemove LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -275,7 +275,7 @@ void fullyUnlock() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public @Modifiable @IteratorPreserveRemove LinkedBlockingQueue(int capacity) { + public @Modifiable @IteratorPreservesRemove LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -291,7 +291,7 @@ void fullyUnlock() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove LinkedBlockingQueue(Collection c) { + public @Modifiable @IteratorPreservesRemove LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 4c33b12262bd..6b851777c853 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1179,7 +1179,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public @Modifiable @IteratorPreserveRemove LinkedTransferQueue() { + public @Modifiable @IteratorPreservesRemove LinkedTransferQueue() { head = tail = new Node(); } @@ -1192,7 +1192,7 @@ else if (s == n) // stale * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove LinkedTransferQueue(Collection c) { + public @Modifiable @IteratorPreservesRemove LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(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 69604ad38ec6..d84edb46b233 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreserveRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -210,7 +210,7 @@ public class PriorityBlockingQueue extends AbstractQueue * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue() { + public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -223,7 +223,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue(int initialCapacity) { + public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -239,7 +239,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue(int initialCapacity, + public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -263,7 +263,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreserveRemove PriorityBlockingQueue(Collection c) { + public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { From 071ffcde7f1181d02ca4f370902937ac537d5309 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 29 Apr 2026 15:37:18 -0700 Subject: [PATCH 066/119] revise javadoc for @Modifiable and @Unmodifiable. Co-authored-by: Copilot --- .../checker/modifiability/qual/Modifiable.java | 7 +++++++ .../checker/modifiability/qual/Unmodifiable.java | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java index 97d492135de4..caa15121e762 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -13,6 +13,13 @@ * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to * {@code @Growable @Shrinkable @Replaceable} on each annotated type. + * + *

Some Java types lack methods for certain kinds of mutation. For these types, the Modifiability Checker defaults + * them to {@code @Unknown}: + *

    {@code @Modifiable Iterator<>} is treated as {@code @UnknownGrow @Shrinkable @UnknownReplace Iterator}.
+ *
    {@code @Modifiable Set<>} is treated as {@code @Growable @Shrinkable @UnknownReplace Set}.
+ *
    {@code @Modifiable Queue<>} is treated as {@code @Growable @Shrinkable @UnknownReplace Queue}.
+ *
    {@code Map.@Modifiable Entry<>} is treated as {@code @UnknownGrow @UnknownShrink @Replaceable List}.
* * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index f8d2c6fdc043..69aadab79673 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -13,6 +13,13 @@ * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to * {@code @Ungrowable @Unshrinkable @Unreplaceable} on each annotated type. + * + *

Some Java types lack methods for certain kinds of mutation. For these types, the Modifiability Checker defaults + * them to {@code @Unknown}: + *

    {@code @Unmodifiable Iterator<>} is treated as {@code @UnknownGrow @Unshrinkable @UnknownReplace Iterator}.
+ *
    {@code @Unmodifiable Set<>} is treated as {@code @Ungrowable @Unshrinkable @UnknownReplace Set}.
+ *
    {@code @Unmodifiable Queue<>} is treated as {@code @Ungrowable @Unshrinkable @UnknownReplace Queue}.
+ *
    {@code Map.@Unmodifiable Entry<>} is treated as {@code @UnknownGrow @UnknownShrink @Unreplaceable List}.
* * @checker_framework.manual #modifiability-checker Modifiability Checker */ From 0e18efe2cf24c52042b1595f20a916483a3fb505 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 2 May 2026 13:45:21 -0700 Subject: [PATCH 067/119] Rename `IteratorPreservesRemove` to `IteratorPolyShrink` --- checker-qual.jar | Bin 255934 -> 290638 bytes .../share/classes/java/util/AbstractMap.java | 8 ++--- .../share/classes/java/util/ArrayDeque.java | 10 +++--- .../share/classes/java/util/ArrayList.java | 10 +++--- .../share/classes/java/util/Collections.java | 28 ++++++++-------- .../share/classes/java/util/EnumMap.java | 8 ++--- .../share/classes/java/util/EnumSet.java | 30 +++++++++--------- .../share/classes/java/util/HashMap.java | 8 ++--- .../share/classes/java/util/HashSet.java | 14 ++++---- .../share/classes/java/util/Hashtable.java | 8 ++--- .../classes/java/util/IdentityHashMap.java | 8 ++--- .../classes/java/util/LinkedHashMap.java | 14 ++++---- .../classes/java/util/LinkedHashSet.java | 10 +++--- .../share/classes/java/util/LinkedList.java | 8 ++--- .../share/classes/java/util/Map.java | 8 ++--- .../share/classes/java/util/NavigableMap.java | 6 ++-- .../classes/java/util/PriorityQueue.java | 16 +++++----- .../share/classes/java/util/Properties.java | 8 ++--- .../java/util/ReverseOrderSortedMapView.java | 10 +++--- .../share/classes/java/util/SortedMap.java | 8 ++--- .../share/classes/java/util/Stack.java | 4 +-- .../share/classes/java/util/TreeMap.java | 22 ++++++------- .../share/classes/java/util/TreeSet.java | 14 ++++---- .../share/classes/java/util/Vector.java | 12 +++---- .../share/classes/java/util/WeakHashMap.java | 8 ++--- .../util/concurrent/ArrayBlockingQueue.java | 8 ++--- .../util/concurrent/ConcurrentHashMap.java | 10 +++--- .../concurrent/ConcurrentLinkedDeque.java | 6 ++-- .../concurrent/ConcurrentLinkedQueue.java | 6 ++-- .../concurrent/ConcurrentNavigableMap.java | 8 ++--- .../concurrent/ConcurrentSkipListMap.java | 22 ++++++------- .../concurrent/ConcurrentSkipListSet.java | 14 ++++---- .../java/util/concurrent/DelayQueue.java | 6 ++-- .../util/concurrent/LinkedBlockingDeque.java | 8 ++--- .../util/concurrent/LinkedBlockingQueue.java | 8 ++--- .../util/concurrent/LinkedTransferQueue.java | 6 ++-- .../concurrent/PriorityBlockingQueue.java | 10 +++--- .../checker/index/qual/IndexOrHigh.java | 7 +++- .../qual/IteratorPolyShrink.java | 23 ++++++++++++++ .../modifiability/qual/Modifiable.java | 18 ++++------- .../modifiability/qual/PolyModifiable.java | 14 ++++---- .../checker/modifiability/qual/ThrowsUOE.java | 3 +- .../qual/UnknownIteratorPolyShrink.java | 24 ++++++++++++++ .../modifiability/qual/Unmodifiable.java | 16 +++------- .../common/aliasing/qual/NonLeaked.java | 2 +- .../qual/DoesNotUnrefineReceiver.java | 3 +- .../qual/PreconditionAnnotation.java | 2 +- 47 files changed, 270 insertions(+), 234 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java diff --git a/checker-qual.jar b/checker-qual.jar index 041b4630e0bba72458e50ca5160922c7c943206b..2307f392bb16d457f805a0aa1f5a9a1ed67d0f90 100644 GIT binary patch literal 290638 zcmb?@V_;=_mTzpUVjGoIY}>YN+jdfMRcxnXRcza=*tU~*?(Lp=eQ)=ho;z#sSC*lp7 zO#wIf0WQGf|Mx~20a*!A5hdl%GNLy!W24eibf2f;rRb<9#wP0&8RnQa_pZn2h9t&i z#%UyIfnkVAWp1k_!XTd1sf?47(9pDwPAJR@$jyo|3em~-i&73gnVjr>D!g&zNZv2p zEjWHQCNJJcFV>`b^bEapymAEo)AuTcb(f3>yn!j$pT3v0gpi1=lE`OgcV`ntJ-c)U zB)l{ZeHwAbV z+CDR%PO>&9l@W`WR-Pzp4nCR1`uN*DJZyAkWZrwi*}Df!S&6>~H9l(~-b+uJlTZ&y z=ZjVO2`l8T54+o)LJbI2Wr`-`mk;KwVsaL+=NE>m4wFxxjutD) z6%a#q4aK);JL@TQ#ZK2MX>W=tjYrg6m8M|Ugq%4U%i-}R9*nvURrk&k(bPeV$2wrH zQnUY(+oS{phm&CuP6ENi+B=sJws_K=F(wnRdGp;nxFB&5Y?moC(MCqhk7tlmF0A{J zH*^8%&HzUJRyku3O)0i&Az-l=i6}^5!)d|I%?VM1ZzISB(&mlD!mB-M7 zdAu@1_(u}_9PK(2_kjxFN%;zTTF=hB3w1eljsL>(r}qv`|S#a@H>e*1hBD!YYWxP^Oh497) zOZkQD&;CzadcX*yUCi%y?Kr+W-yl|K2gMR|6Lp%?50ZblB~!5;URq=wUTPFILn3SM zCie|Uw6d@XEFh;i`=xlxg#QHh#;0=f(5Z2{>;5sqV;xcf4Xh*F5l18Gj82uJE8+Ux zQkghO#9|?KQSGZvSc=PczZ=%0h>z3hsPycHa5H+y`xEcbh6?BJeTkg3ad^(c6(Q;E z&dOy(q_mP^(@Vh&BbtuAF`%-Xltxu=+Wim1_TwdkQ%C*gZrtU3_ULjpbi!XE&-(m} ztgGty=@&#OI@7D4W;70?b>e2*)^GW~DDWjmW4yWCJZUc}PF~y1#%e4>YAp6CwuO`* zmP5PbYh)PAg16X2y*Fs~bYA%WiOc}T|4%js@EMSuquD!{`Y%~%uS4}OdL%e z4Qx!@>>REB%ZKp(Ul09V%76JV*}r?((8a>q*u?R_6hi&q72@DxVEs>$q{Zp2$^q^Y z3JL_o{g)&O8CYAJ7|WPAo7)*X{q9;ZiaJ)S{7Bx5RqBUAHi;R2{!;N0ck(4s4oP8( zlIocYGb+Vgcf6MK+dj+rc34D+oq*XuL;F7H_aULB z^<#I7lS52RL7(DgnKl56Hn(6RUKk(8^$;x$$Q5=_nPygdQZ#Qtxe?7$>zS9xVNs|Y zm=pTk-u628<*~mp#H1aw1(Q2i)1w&^_IeRW9LEJ3Tp+4)YkEo#&J$Dwt|9=KR8;PL zE!Y<_tXj-0sg(QFigAjAX4ng&S@VIUjb5X*pm=&_dTb}E9Rpq~z%8hKb$a7WJh+=U z8h^{yU&AV^fSw|*VA3kJO(SlJ+k2d^s@5U_Vf8yMy{zEw#=`PWua7IJU+&4C>CcgC zYo|1F9a?ob#s2j*46^R>)2;77w_Fgesf%EtZ%;RtVnRZ`Ea%~M%hdTGN1zlFHSiN6 zdR$Niv4YN_R_}Deb|Ib-9DWx;J1X8E-C;!}GDT6lNw2_vRxM5x%UR5NhjyPwT-oNw1@Js~r13iD$rjEz zgKEhrW&>O}lKFBqwH?xavBO8LUTX@Jcjz*7_=_NuN{8-&l#^x`fkV=+m z2unda7wBL9RZ!>hR2X^*Rnl9VmEY2OIuh~>u>>#pJ^3LAg}(<9a^Rto-8Ig)a(Yif4G8Iuj#H203wsF?R!ZPW8lY*03*cbKcK;NAuM%uJ`~TQj%*!qyEb_32H6 zY~7@sK>*#xD#mrx2e%++Ac0>sRS=*1BnL7;dKvib62stYW5_NhsD*h2@-D7kJwEu| ztsRVc_J?66Tut^Qq2(Md_ODw)TS$~9p)I|sx&>Ov2^w6o&IQX`%kJ&FSs~X>=|P1V zyV*ncni+?Ck7Qmxo+72k9oGhR`V@Q^pJ2F@14MT` zoFjcf{s^!DH#git0LugbScdm60Zh@v*~QV;Nzuf}#KP6Y@$Wn{ZJQ3@nFAWtVrS^Xvd5xj^AuBSYh$Os;M850kkl9ZOr%W2 zDqWXm&2=6?`b6Yg5-ukFpIIZ7`P2t5L7OnGm}Q~|)J0Vn`bvwk;0{^?Y$s6`i^z(< zm)+DytMBe!@L6nBsP3I}bBHY>jS{j&iGaaA!lA>*N+vN^ixf{WEMaFQ&ZvH9#+-S@ zJN9*B(SMV$`HB;Hqx$4SJCgVqwl%A^`l%5V#~tc4U=LGvyDLoqDPGWoG=RkuvcW}u zXf^tf+KE zSa(ztqrQ2t#JOY_3OIOwVubKm-Qa~sOH1HO7;cK&(X~_yXDZW&7lT6Tu1Jg6Vg&nh zqDYjt{xUctt~U1+y(<)BwL;MqL!+_2eIw}w_;+sVG>V@k2+(>Ji94Heep$t0B=o=+ zl5=TgCt1x6v-oDjw1^DWrkE*Aw3=)R*P4Z+Y=x0^gD>9g5*uQ}YdNEdwS(!*onGq0 z%T_h{L}-qPC?@K<;8KCsl~S%1u-q5<8-Iid02Tikt!e%pM2voqJvM)fJ^vKb{!tXe zUla8&V`Q23jWq>;9zno?fCT>s^8N)wDvjE%G9a~`&|n<*Bj935*fkU zDVSn{xmPknT-KJ&GCC03ds7<+<6BL4!$^+u636uQ zO5El^4LE6_cWN?KbR9%R)d1VT0mLY%Zok8|OdL0_nDmWiQ2QILrn4qcc`BId1p>k+ z8L5K!B0gnXE#hCq!kA9o=%!xkBt+x0z(wwZ}_x6}^|T{K_+2y^fu&%6qFOOw=IX3f!mp~zz|+=z zrDm4%PnAvi7qCSi0ExN+NL2j)7lwj%&dzo=ztd@Qf{bks15(HXN5A;GJlH;vGJ1$< zK%X2MN`sDwET&*2YH=)8B$C^OzYt};h>2ND=Ya>)B*#}(ZqYbu(`l4^^sME z<;LQPBSucD2UVh5Onoy?omb>~O;6+#7mv2dlP#DNrgQBa(ovtvnnh+=F_^!=)Iv{TzGObno!)xs-Rqpz)DQ5UHZzsxi5)|ggc zmoxWeZff-^SA$${4$t`c-iH%wV>q^gvuc+e?O_*-_sG-=&Q~^(_`=-Cv${UN!dW|T zPYh|=$(g^Ue+Zs`6mR0k4EUB|q!GlFH zq}Q`tbG!S|;T;r~R=DgI-1V~{=O+3!9Eg|r&6=Rp6W;LHbi@r~{;@2-KDk5(zVMci zu=KjQh{r|e*K2NqjUFy%&a@cv9e3{4tJR(T-tmwcLFx*t%96C;JwodG9iUv&<_@4G zFd!ROe;G^x!)W3;em@^uO9G-{Wc$W=-@;Uu!VOeoQL4K8%KcNdi2GcVL-P*Rjs45z zyoTOhP3CkMEq%;U%O(8RtpFRZt{A=^kB8k-SEQ1FElK3A$QN-5C#nHs+pJQL4s+Qd`G`}-bSPs8j$H( z-OS;VQY9vsk-3FTSYH>KUbifwniR$abuLGeC6sa-NLmbLOi_DO&9>~0T%A7md$}dd zHuM*5)9ZO}qMOC?jM)8hDnZ=P^*GBQNNCaV16z&c;UmFx-_9Lr?Ez53Mwp!8l0Q9LVvyg_OVrQUex1v6dwG zgwrUiWP4Vd;>ZL-zG!VEP?GF>y^ZTwvrRpsH5G|4EY5zQM-#Mt*e0W|00rx14BRQ5 zzJy!>8;?;EQF^Fu^Rp(75!^};Rnmt2Eq^Myi73fMx=>v2!j%C5!yz1@oA9tYq|yZ9 z;RZZOnuyU6)rCx-Oo zUz0mvM$8Vi%M07U$KSWti)uS%8^iS=QDs(}bLTT|;+cLI6V*b1F%tB`L7bDg%o3~m z>KCdf3}vqCigxiai)sY61Ff~a_jOX?ESoiwG9&Q4jI?0k)1rn>G0aH#rx{w zXUj|4b!6A&1M#Wf87i_ThITM#OJt=k%Q%I3Pzi!<@0Vlj2lC12gzj&q-1=REXA@@T zOX$%!ZAoFO9egQHRscl za7x9p-nRVF_L2hZsvWgKJTyjZ6V{qE7z^b!6Rzpn7orV86X)2U^cGmdKeq>}2vZ@@ zAkm4SaiGtjpr!GcS$j0&@#tZh3An`;nTM7F0&)iM?WCsaJry6v)pryRKT(y=RzqGm z)#_awmFpBiQdqfMUq1PM$y`?`nm8q=T$(4od_3)dkdbR5b(k|NVR`D9Q4F8*gyM=6 zGnNYkZ3ej_xsw~-phLEceXFCv3oC?Xw{mUw`%_bK#$+^x2#|nX0p>gZlL-BuS z_XypfvI-~);Cvp`kj|tuna?4eakLA-Qw-WGWU@mI^l_IL45cbbDPSXCUnr$q*ZSIR zVL|$lhe@t4!#{t?G8*A8V~%FRm`s&K!?32BZ(D{k8gpW$`98cW9rl2}Pa)71rAQ6h zX&+z^OAN07Wie$>)x(6P296p!E}M17HJR#?ULkqkwgXRtg`Kfa|BTg>U#!-mGnz42 zevnB~qG+m_ty{z@my&5u+8@2DKUP)9>TvT=FXDr`rfw|lV0e>xwPC&mZFa0&=%QER zGZ+>IjN9{_F>0Cto?J)>7Ig7|WE0wc#h`36?_S+8aUP#aj{!LHh?;Ge0>e=klo_K6 zEv^T@X4$M$3T7s$17X-OCf*coBBXMNq0Gc}D^P3aypsOmplAdHJQ?amwnWJ9eTvHy z>JpQ|aW&WlR~V-hLV+f#JB7a|y>)c>ar>1pJOdj75$`DU(?Q~-nwi+tI*yLcFIn4j z(Zup}mXP*}@NS=3vd72fLxu?jE0Ck<0GXDb*g?GbgA$L)R0``_QfPza%)7jB{TZLTXWY{9G(kUsGzEI3ENh!XY+z0fKH-G)FIyYWBQ9N6N`n_ zY@BLI+^!%PCbZH%y|>UH39-j^tA*6YF^OG?gBbVV*C+bHR;E+4auGVF>4^f|)A@uo zuEXnnrB(7Xv=o@pgn}9mFLn#`B{*?E$B#lSH&7L?s#Z83NAXkt1P4de74P!dXBqVBj=$%-fX=u@^T|+6C>HT~@~4D!V;kWoKh27<|3K zW#pxoun*Nvj8^;Ws*RiJW=y`?x!V-CK9%e!qZrn=3LC?rVPvZM^h2N>P&Q81#<>IZisKO5DlMy2-668GQpMft{ZpyI?19(}#i_ z5$?8{*dl$V6$?%lLk7pjn#)b@iRZmZoD*jle3l9Dyd%G&T~>Dblw|%Cedo z4y!0z3DDS);a(r~*jrsS%II@{!bnpG&X$IEAy9RSpHP5TnqHo9G$JyIjIN**9%|US zRm{bT^;I8Kjs)Kmib$c$Lv0VRoiaFRNy1uN|4L*ABanDf!a(VVRm8c&(5Bib>?hU% zW+%k|P$mlK6sR{@gvfKqm>Q+&lNAKd>8s-wi5?X2(HEkI2ovc*fg!xPaOqdi9N~5< zK2>=^|H_LZh#EyUq+nE*7A?{oiOWIS^q@0)B=dRNI_#DE1le==IhB^<749NdcH{1( zZ_DYuQcN<^F)$fMijI-c&$iXbp2t0aR6>8}3_h>>a2L}jitrgWof;UNn2>fpva&1; zjN0Ja?)onXa&K%DEwv473_%kpW${T_vc}Dyv$0{05!8rao!yMxr)FzKqS7VDPZ@L} ztl>W*Qp8zMFp71~a3RUDz$B&15c*E*jmfJ~f;2bcE2 zOZ~EvV+O%&x(r5GLSv17G)|O5$Tt08Sm3XG$vAa0YR?y+8}V$e+wWF+Q#RqTSaN%3BrESUaamhLMOD+i5v3gDR` zR*ve@sBtW*UlfxNB+-=BFslS1H@Q~}M?6fSKO&G_@gfp7Cg|Yf5*I>HLpx3P!*W9g z8yruc(jy@spAO+%S18v)V%I9?bXtiRHNfxax?Y+B< zx|P1b!!1|QvP6ro`<>H)G2QNrVbALFf$SEenfg=*P$BSPL#`^Ctt!&}5Y}x_!{nMY z6+SG4EtuGfkmd$YxvA^g@vok*D~(hCaj>=gMQI)GIeW;pO*aHnCqq2*Gg26hu~=?g z&<-V&A0^jr!p_%M-}q;i3U?v}>1#UD8OtKu3C&=FNq3Gt)F^$E%Fx#XuJ1XLx*9xNe?-d?P4j4%WADf)7W}b z7_Z35q36Jm_wb5YserJ>)`ybOuIm0UkMk1L9*>{Z80DYRcXJ)HBq2ooAhHf0ZM1Vg z)mlIU+A~~wofVX``yN1f=M#iQe~yzaZ{v}I(6~<-V>TJ);&AH7pE#j9)G=NTv+?8V zjV*7t>x0MN)=L_h%#QQpPXx|Umip-l(9hZdq*L<$O9ZZJ;Ar4z_P23lp_0tk6$YgC z1GVTzMR2H8sd=GN)e1^QuN?8X^TOk9_QcKp8YMq4qNI;sHK-UXy}F(b6<6sVcE6;t zKgYHSGBg@)`)`Lg*0&8L)(l$tLsz0up zn9_u>SY~JAWOPE0{roYd)Ua%v&<)mcBnWdp9l&QV2Pr7W1+EcT0JWld9BeNDA5oBqmXUbg!>| za(rjToC3BUS`E8!Oybxw=kYeO?h%vzV#DW^LC@k7ZHq~*{koOMIhH8mT`xOGdbOG& zzm+lY^vRtl9~H|=K)N78))&@L*eS>sVFnyb2$d&+76DM@086W{YLN7>1~7~c%;)~{ zK~iu0`D9CZJbDTqkftAjJsY?YXf?~gTditdmG|BFQbt#{s`}HA<#;b*+cxJ4FzdN` z)q&lpR5c6g>=K2Q)DPn9pTq}`_=5_Llr#x-YA$KDZbz9~)@*RJs;;Zj>6Mzl(y?v0 zJ>3s7ZdkWEuzqik+fAVR$?t9?Y(LECU!TFBY5g*A?&-od2zyCxAxrap?aeCF{k1Bb z=^2DUS^HM^&8%P9O7vhtOLHi@6Dl7hcHpLB^v`)hxk0!)831C;fQ()8e*iN@69*TI zf7!{%RF<&=%sJa%)S_o#g(H5l+3bZAvZ%}!1ZR|$X)Xkv8D4OXb?N)pLRq!R;q`~`o4hy#JlCr}b(WJB5`G%2St1z}@0 z7xFJ#JmRNN!7xy<+A+bWst<7te7ZBzA#Q3g>f%c(Wihd!q_!b6fvx9J#JC7~z6(MH z9cmFmR;-TskoRqg=NHeN5w|Nbks=x^sLc-ClV^;Y&6!bSPGTK0FCo=hA{|4+oB`R= z6w@Annl{DTOZ~oz(c5yBiDNWNMbHyWZo@e6sBHpvY~Gw71crnP$CX+zG2(hy?Eu`e zO~n8Y#``tELDnwZG4i28lh`?k@A~C+zOqI?&=u+e*Wg=Lrxd~AmOlYf==qmRA>3w~N_n%ccIzB{m$uAL-hNKN>t?+# zc3%^(X6+sMe%+o)k8|83%;5Qs*IT3k>VSceA;(J7XcFA902d&68r*QX)@gd@7%mtV zDyARORx$W0Wd2oXRLsea5B8oSdQv;cgSr*u*}IlY+7U{loG zP07r}(3KHASNXj-xIA1WVfQNRzVKluN9+#Dl~~<9?_zmnupTBvp2uMbLd67Au|jNJ zxk_+~?n4(gG7En!X-)22xEVZRyzo~Vl&WhaRC1}EsSfWSK00+cs9SQ`<}_-agOKrg z$us8uz%W*c%i$LxQ$^zXhKhf#Xfp7m1JyL339F_Yt1GJ}YukXuw4$pt&QgME@us-! zOdkG&4NgYh%B_)jn9PlJsdn`W(SMO0N+k1`D9JM|3dr4Ts&PJ6K>elUO~2JyYPoqK zOUtgc0fA1o%s1@Cktbt|1oG}e;8*J+ST!_j_n#Wv0RQ{XDc`?cTrsk&dya#hmb4Vn5-M0HTd1A!-%6ZfHF3V`VvlFXl%QM4 ztq$va{#@EWQVjsy$;b;1eX3x=}bz{^u`W2g_2%O_vZVzIRl0huklvh zs=2PyTg>Me4d>~Jyt>G4dMa*>_Cop__o2MRfbOkh9QWs%@WpbIS17ioC=15SL5mDr zp)-ws{X$rq`0x-n=*{c9qIj8KE=wB?QW{M>pIV^1>uR zyYjneH&Zvqkp*UfIBFv65bGGrQozz==|U@nf#NQe7@2e4u$6$vq=RC-l*wjDheD4< z3R0TMjC|rqG#n`nm?^}k_C)q1(zaEfbCDkklF=aAy?6GO^dX>F2 zIC}|L+w%g>sC)Ubmk;2vr^S@O0 zD^w`VP4Bw_i&eAR zSU(j>5}pj;iz0ZXd7Or~?Mbg8c-jivV|{RSi){?8An0MAZ^4?%SX{?li++^rHeVtT zt((4`Ml@@hb!Ti2)KhRkI+afjWi2}=GP&rKqM+Yj;BYV1iP2PCFwLF!)}nX1+4BC= z-bhC~Z?F~s0z82DE%VnQpkixfYv*SB|8UOaglXGA2DH$N7c`3H7$z+rAUg(0#=2&X zz9^kkMZ_s!IvNq7@QV%<;BoDtHX@3>6Tj!|kKJerT0wcvJZ{mf90Zop%M#}qJo(C6 z?ShgzV(LS;;Tb9-;?ZQ*%YKCDB5BbiiBdQwL5UXmwlR6^H91HQwtk44a@;Th#F#zn zJ2~qgirwV~OJKmF8qAIM3H-r0S#(t zY^~FBnl<+V#Wm<3rkR@f{=aTTdjlgY0H^-n6<(hh0T{r*S_Ck#_HX4c zhO{Sf*3fnb!RjG}w~)@PN&58*4YbAaiSMI*L(8hG$EJ|uc_?o)s>{j{Q&M+(3`9+} zu#4dup||gIjlK!O={E1vc?hGO2#Tqv@}~^#-a3f0mD8%aXV1DgDKR}#{h*Fx)y*pG z?7K7TUw?ctz`OisG$Z+UFJ@|D>tgd?hB3Sh9x-GAtYkarS837))ww@d@4N!g3tB?o4&`}; ziFj8RmE<*Cl5pnojo@9PMSOz&?|f0Kk!@31=J{2qUkp$Ff$uL;x9if~{q z>1ei}ov5d3VA*)MFyWPn?)&~SOd1I7El9(jV@(5A*`9FSKCPj*KX7L(2|7L?d7aW+h>X%E^uW*#RQiW;$-0D<_ZeoYp#|JcoHnHE>l| znfd*bCZ-1Q(x76=GdqVZo>XA((J&#Nr&$au+AiC!yf~MsFY3Jm(xcqL`mIx%FvbBq&Q=@jao!s^oS>} z?QWbKv@n@wXDC39gAZ7b=lp9p5wf$kb5sI&MnW_SJXeGWO+_26fI>afDA(TCZyp?rmG)PP zJ6>o>{j6N5H8JBv&@=B;{7?&GBe4^XO{Vc&enF9O$_gNXlNA)tiZe| zm?R)xyCU(XoRpGpaaT!9`t$|j0a=>;r_dU8K9CC;yx#^5V>NExcN`C<6uKA|`4q+S zZ8M7~9ek+|ALKE`H9vEddp7TTepL;D;$qwBKYj#06pimi+N~CuldiS97kBacOxlBs zzNaxy-m*g5JWlhz>V-;?sQ=9KWFRT#Y$|=yKqd24^E&EdMgCv9f&oszl1j`maw_GO}{qp6yJ_EZe^Ww^%^qtVL12X?itIw0gMU4t)8 z)l^Mpbo!F$Qn0tYw4D!b>^-|aleEK*d~)$E>C>!~^ltr>05DrviMNYp7_SZySPRH| zOj=u02nrRMw+io4LKN>Q%1JKdlXnVJuj}0eFZFfU&=dFBeBA zJ4a;?`@geKoQ!P{1Crz-K`qjIHb6+#&nk;uBa(GhGLa5?`TT+$4N zbuN1A;>>&rE$^f#hps_bgi+9re&m8v$1_FBVOiXugS!9l^!-@&zRIjGye~-mQ}fpPUFPQ;;SnFfgKvFqauUpIUxnM1 zE_-7O(;;iLub?A7Q+FSY@}#;;KDyTJH{GhG^;xuS2Ns)cta5=z*|Ox~kkgp2LR+j& zdJ$wJ?f-nP3+?R(T58$<7@N*I;I6=MSoGpqSkh9(gq%OF3x{r_=L&d>Jz|W z7#JySAe$}V=6b^bBJ@y6j?-Xiht>*1})={Q}66Eltf%65F5sn zHid*l33!b9S@KRWb;+{NOJXsOhaP#94KTUF;c+o?g6YcL2boFS%9eAQ1+ItNW^J85($F)o^ViU)pE7hY3g@{}M+#7Z%V zFu@?f%Ex%(YbPs$O~ipg^dTd1oc3nROTb%h?@*s=W=l~3yP*N>#`qVwSM;~c z;cxa*6!?8_^aed>mly}(21w7C8759hvsV=c5DH3@$20*uT#-AN?_LsQH9-Xoo+PHG zKe_5w6ISH=t1A;M$1Qs+o#!qWTE@8urC5DPK5mueLZ)P_G6(HEi8T^SNwJK0JZxgx zYRc@E+&>qYxoC_lq+Dq7(rZ^Ewp>2TEw3$To=rqKIikPh?`KcQRUK-6eo02Gd#4Qg zIJr{SkH(^AJ*^j%z!8-WU!MZ15&o8j_nOA-9G0@}$2+9g++_(F2<_ju&Tp4_-wjkR zVCGfK&MM!iFV7}mf%ll2*0>LSf8<}>RAb3q7r|^CD4>m?=5RN#!}=Zv4z{5iFYiM)Gb<8) z+g!Li+p)X7<>l*^9V7hQl41O@C20I^mBqtLTL;~dbF*ydn!UHYjb!;%OA_Mcr%hp5 z>4|9GnOZKQA|8ap7c@ASQ}F6r*>o7WFGa@8=#W>R{^*jGZ{)Xo0Mq6I(l7SEYTAFS zOO>X7J38V0pjI*WDKKFNR8fVzTU?w}y|3g9l{2=#!|+5?jjcMa;n zOl2}0Dg|_PPVJ4Xei05&bww*~#Eg6rT%I=yTGgLucOLdVGLe5xEaIZK$i zrF^{?tA~LXeP_RXl1+UkL~A@x5mN%EAI9*W7CoX{V594yFP(129$*w}wkyguXTG<) zH(lR2AlxT}`g#W6Q>oCNXj}8N{Uw!KSWRFFY<{)ff=SAEVA}BtO{bS{)}5VzS6G7C z@2pv8sC`|+k@gu`j^ZKFm?P8Y>;7o#^0tFBJV73YgExQtt3Hs;18=N}O3?no2%`-# zI>#HRZ09|rZhz@pDGYUIf$AX~V}vqf{5+xfTAz5+NHjp35=YWR% z2$tpS8Mwp0nVg&wEcY8l?TkQa*NlsWQTWF%9r`JAtK-$vQw}H7ed+!L7A<1?8q#5y zM3zY9YLL!m^=uT<{@Tw&V&m5V2F4=&A;E6c~iPTl( z>#hx>RVWMEH+4n~?(jvs@RTub;xb0AvsIkq!bTI{ptLI z{kZR1H^7Vp00!Xst7cTO{jI38Ftso-{@t9J0CWC*6=*36)%h5*fD*SJ1|#PivxEOx zsXiK~s*zMBZ4*P_`%4LXOq4CuLOWD~`;e1(7R)>b8`y$P@Q8%XunB^cXM^p_I}szJ z3{@5mt*Ao5=m;mG++$!Ke;u-U^xa_t%l1lH5$TQv4`)OoIJo+Xsxvk_#Uy*j8;P|k z?2nb%O|L!6nJtQiH@Owi4VR)}nQ=tk>C(10#Y~a9Ywog_Qz;FD zmeDl8NoL!?=_h;4ZlnPS>>F>ShERFUt~>>f&3E7y2%9828s}zesJ4)$gF_B`h|v1U z;V+Hn#sM|!<;0(U1@xGL^3Mu}Y6Wg)#fAtGc`E1>aU|YK1)ykE?ih$%9@ihZ)Pj}R z?4SkIT44tuyk>xM2Tkzl9H(&~2T}#Ngj`=V@>G+BJs9z2qrf*IZrl&N`-bZHUE4Wc>d(n4{e@`18+!M^|Cg`lY^7f`t;_%y9 z+bP;vCpDL{AyW=;!3(4~b%v`I*^!I-bbXMVQ8@e3nq`HgG9Kw7l=t(?HzGL?x#m~> z=yk1IoIgefh@M0#763Nd0ZB3IU%-aEowdh51poNI@9Fab_Vj_M_kpYfHA!3qL}sfG zVSb*IHb?l`XQ(1?pEm@Mmx$DJdA+u?F-@jKC47P!Kv%YwPdaoQMEAv3^ZjHV+oIsS zdTA*cuDrmGc<~xE8+j7w_#@^(7hC2c#vIM^tKDolZaIUYhSe44_dG;x_BT|mG|9+& z&I|{&oQv;K=?}%tEbxs#7$ad&)MGzHlBGQI^Z29v%$ z#1}+4Uy^92RpQr$f#W3Xe&5x1yU%3y(x|;VPF?S*I(AH%z@Rlc;x(ri;ru=r!(>!i z;;w@jVWTS~C2stEcu$*9csU?&Jc7dFtw0Ng`kWPz3TI(kg|!N)=*Z+$)vDm>)j{{^FDtk4ngaWTe zsvw8)YG^$CtiVnC6fBGr6*874YHV8|5b4xNfGw~P8m*bj8S^!*<$ z0H_HC=h8r{p+NvHfJ0_5jgGx0aZLVR>JW*veeU8PS|+04md|GQYm5y;7#>}5hnoDC z{M?}=B#hg@{00b(LQ|wq{ggCR{0R2J5tlcJ6~7u>Ju7}2bJ}=}IlAT7szd<-yXrc0 zuc+PuIG@Xq5I{aq2Mr1gos#fN>Vjb1T;4)qZvcW>LgPc%`P=R^Z(}^2GC&Uo>movI{;LYtU#Gg|TiCQX|a_Y$}PUhtG$ zTk882{-1=xDh)NU9bGupD9#i7Ry$o(`OBH{G9fElvxYN+Qr0%x$~*O61P**Uo{Q;N z3loYh>VVSoakx7ZzN$!#&zN4kR;G{LO!mf2#TAJa-eegWCHu8HZ&NkUp8!%d}aJf zt{62ce{K%A)oFNum-h`YJNxq~Fxbj%*%$MK zl9X}SS`1f#dBT8SJ+U{kexj?!by2Emf|v_N(wHCMe1^H`LOTo$SQrRM6s^-DNrP$V zJs8gUN@H!a+&Exh6gctXeJ7`7orJb(-~`dgzv%H!dQqN|RyaQLq<8T1fFO)0mq><9 z@zcY=h+IBi$D|-i2{B+p0aK+8-4ep+BN$$s(V{nsl#ysKe8@-)vzeIN%rT_T(XU zsk^4IAbpc#g$w{Cn)+ul|1~_iga%N(963 z@UK4wQHt^s#otIq1fX|;zY2L}6Ze0?F#i-qQH@c;YRbkDGRWzjq|DQkXicPNe`O}c zVstAz)cJnApG~q1fjAZn>`Qm#&`z0RP;+BydBf5Qtt+4Y2yhe)FS9hl^9ga&Cp*me z4ed&zb&w?K0JN`L&;3p?>O0Nut-jfynV(&V zO|>Hz=XpN)XCmL)#*vf)?gei5PmuX|5L}Fy-pq>0HE$#Kz;a^IbGSp+1fd$TJrrkgPJbCck5EPBjCNZxworcH< zld(1qwOb+81I94YH90Lzu-I@=Ry8-;(&&&(8Sx%B&a$HUF~fm#Tr$GY)O?)1=N`#I z?h2j-DOBG#T}j3|UmEFpU_dmEeHQ;zcQadgo;F@qNcIEq%iYF_E8bxb33fSgs$xf8 zQ~C^9--`b_p}L8Zri0X-QCzi~QZhwM79Gt78kMGHU0x?T%g+`I1W3{3lWp6GM*{CJ zyB%xAY+kox=wW+gRxa>oUAcK4z?K zGgnLRGcz`uOMAU}Aa+P2v5V+mBIllF?PS57G>f6S_%20++(bZ~KNaryx);}dnCg>f z6?uQjzM^?V&-Bc7n>;!}Nb+J<7_2IU)~TjUHt{$@n@{)!tQL=iItpc=>bBv`Qzlt% z=&1Pv@*eWwPYvB+p^PGTfQdH%CjPg-zwu`#``yIyzt8UezP0|32YRi68UTd?NWZu; zf1bXk3wkO8w5@Ljrz|khxh{n~zm152(ejSnfE_pefxs9ESSc||1w*((NMvzy3iUfe z98w)483CDGOA6VHHZ}akYhq%s8S<6}Im@D;sWD*?W54uHtygkBv?}K6zB}HnJkG?a zZJ%~(xV{&jskTUo+*o#IwwubLvFhjg>Eqy{57|~50i3K+!6x+Rmi5Bt$xOT2hoRcNJ#@ZoUV1a% z6MKN?{sMq635`7D3@LH`QzE5ZZUjI-%3vz{| zIR-;PGeBYlN&fXdHF=#Rkxo91dGP~01Tk9w{@BDR6O#mu>$hGL-(h{U0ehs)V14zg zfTsBV@OC6=qv|aqD3wd944&mx33LgyxHDXxYeeOPZ81(R6uXwL`Rx9iHdH3LI`mS; z@g6(5tJ_h<_|=8Et{#d>!Hg?HPm?y(4~;suES<<-QZ1L=AGS+tL~oWO8OL#roK|Qn zYpBu1qmO%F9tLtH&kCemh6|J1=9w!?c2FkSR0QcK?A3fRV@#0!*H*nAY$JILV5)RnTFq_xESz;_&USG@i_=#cll6FZ{ zeVm*DWusV>$lgMWqIpOW@}+4O=+Fe#!4~OmlBR}pWZ*L$I6e0M;zGwIp4QZDHTlP0?$8iF`soc#BH$KullCA2}b+uKBzK}Tvj|M z(>A0h_oy9jQPYQA{pxWLUFIkz#78i)Ro8eHM;PogR~o1=Fu91gR_v=KwEkH#9Ixa@A`oBvR94T&#*(73)3z z;f_d`QdfnLayZHE`=t=s4f+Z6&JeFqIsCib&(T$+FKYatq~4QQ@`&Gm+Ipd$nRRc` ztrBU8i;b%FeIzfkKXb|$un(rFL(5}vk1ed01PwdnL;DcVnRN<;qjv%77G|mi9hLc3 z!r?8>XXg-*NGQm1ws0hFHpWCU&5c6?G7Nhh31ZGq@DRMg*S4|iMEk>dmtN^zz@Hrq zSO?fC;qwc=&y|sqH_K?wiq!>19ApTC`s2_3hx*I@!i?OM2)y$6_66uJAP{p=%I!t72` zBS@=CD@a7}BX}mnxm{XlmNZL25zN!qX+MjESjnQzP*{Gm6-`$8^8I!d>p|!Y&(VMZS?W0uCwy=L>R}fVZH4&9qZj4#)!1 zify$&bFXN#lng58Hv9BS!Rc9!h^`3sPOf~q0@T1zQ&CufMeJcz)WVJw1PdI7q_CTaaG zH<1X2IB6P@uwn*&QucnVr63cqZ)$!J3dq6oTwQJLE;m0&KD|iD?e6h20OUyJ4SE&^H&5ES+yRHY@49A_cdr_1?c0Zabq&1HR+>nw;LXrqG;(KdmB zD)z-Lx>&PiLrhXfLMADN>7$Uo(VgyF-2XYic|-b)uykRY=W z_Xnv`Gias;cdHVcz;byvz9PU?W=!PNGpRI*KACZuzv+x8g|5G^HbQ?twxjbl#_RVB z8(Otm0+;rQF!ZmYKnC{*Ad~P!J~(Gow>m_*fH#rF4Aj}sZfHtPNak&3zkBNAWF0o^ zD{se@xvxfTw@sk=8pQf48UyyFYA4adO8UO?`VjWP^0{?1cW}4*2jb-P7>d`wfV(6m z8>JjXktr)XSw=!F(b?1!(-2zWY73MyNg<`2W^|G;sFrrc_4y2Qw+r`4=t75&T3Y=y z9iFnZ8erekva#XBsFNzGRx=gKlfLzH_ zgKrUn;C4=P(O(OTS@`CGP0R0WrJdA%$?9$;)5FgRBRVE-@rbrQqLW~plH7xfk#!d zAgBG}ash*3JD4NaP;tapRdu})O77CobRgD~4=;)ILge<;j&nD<=LbtqQ0W*3%xvk> zy8@qd6zNzB9Lc$6-6L^sOdy(Pm2X9rYFR~BFM3+$*xxM+9a{=%^_1!0)Is^7>|K$7L=`BrXN_W3|;aC;Ne(3h#g%CR9{Et(a|n)^XQiW5A5G zi7VbPX75UvzpDjCF~YG9GgaVo*M+}jy4a9pA<+FQT7r)%<$6dNk>SUm;O7iVps@pfG^Mi)NPq@jJ?UJJy1ff)8f+E;ov<3g;Gs-&|g zH0Im;yrX(u9L3(%6z(EXX((fjfQ)0h?S&U6D}5XQr5}5d>X}RQgw2kDrMV7s7+Dm} z)QaMrf;Ir!+qHe^U2ke!u`P+-|9KnQe76G9{412bRlbE6Br1uF{eG%5EHj0s^s5W= z*V8nHlaYm*@L0F~wx~wb#6vfF+|&VM{X(csE*~TV`Z4Z1blGz0W$79m>4>Fx@@qc> z!nTB~@l3utd#ZG)Z%Z3(9DddUoe?n2Jr_NPpG^D`Ug6Tb8!JjgLy%GNtEdqIaXvZ{ z7ZrNoXGD^>HNyzON8*8OllxI%#X2cFYtCFeh7 zCNvGd1Rf8^9dfmjnTCMZ9ML#dH9D4+fLd%YdYkwsiJ8~2t2Dg4&1wFn(NA2!ELT9;3@v%`ox<;wojz+(e_ z8Q*1q=D%~{xVu7>HCbOtjlSt1lAl1L)`RX)f{yZoVVET2cWbS!!41=uaL{%z(>@_k z+00*J>CQ8Bl^6jjz$=kop+k)vp1?qFo>C6lPZVs0cVPWc;fV5Jne*~nyYPN^0(C?0 z*eo7)K*~gYWXjH9J?m-r)Snslo9DhJftBE zRuiQOBhT`ISpMkK1#@IAB~rV}Jn&l@P)XfaPe+F6wF#)n5AsfG+Vn7*| zI)0$o&-&0hPAk0^2j{XSZX#zNAVLFG!XQc(eU>YU`OqCxf$ho^IY;f*yueZ1?8i(S zzVbVcUN?U-M-U2+;j4`?tJ%LQm013a7x`?m>rjMtXV^%D;Ll$x)H+`+;)TeUGrzI~ z*~MfmmtbKj_w}W`djTJ8Mf(85izYNP@ro~+bmBPJHC0aBV_Sp&b}^Q6JWEQSlJOEr zz0m{ZjuQI1ibLkxxADtJx5oBtbb$=dVb(1X>dzMv&~5J?@67011qm$y;}@59$!?3t zTAR1mxFjz(ByTZ#ZhShz2P{U5%gHCL8tu7k2vukkg0As9dg}qDF9jwbl_qGn6Dhi> z;;HT98-Lvwq#)oKI|Ee6x8Q)C!T+!{68^1t`)y!e4}jtU2Ic@L9wJRBr_cco1hvL? z)=ePDDTMqzJ?xk4rSG`|37TTo=%A06xzx*M31v%0iG0z;gZHAJ7pOIAK=@0DM$nRI zLIU|kdmn1PbxS6YRz=LSd%VWA2PEu1QlM|8pGmqI)-E{V8ENhYjdv!CJRK22u1}RjI45aw{}ne;liJER!QH?G z)8km(_ACXdW$;T=GLOD-4mlPd{w{U{p*4r8_H_(J(G;~|#iyS7Dg4u$ICjhBOmi1w zBfqRF<)Y$*79+7lZio_y#cH9l z1}PF^V9)G-?`N0#ZLhYK_xa4J)S)O+yV1!3^)pKvv}mMq2UnLS#i6Fz7ol1|Ax;{% zqZBxFdG6eqxNYAqm}2EYZH|xzD??Tm5B~XVvoT_iqis%V72&O!Lkh(9qmFoMhfepS! zxE>n3ush>++BW(#LhqbMK<#YYZ{uSVq-^LECaMe*1gEd}-j=4LMkgsfqRSLY^244-+(u%h@OB4Z7n3)wzR+J_ttnp(YDY zY**rL{?y3P!k!~fRb6ExK~p3S__&*Mu4Xfs2nL<#=lU++v^-H(PnHd2RWjh_XoAX> zw5S2`wz>g)H6Q#jMHq^%@>UK&`wx?!dvrJzx;ih!$jRZpV9_n|vsGsWpBGnDv|tnT zuMg;|tWYHd&}Jg|xAso{x83nupW^oi^v~;O^3&2ifc3LW70Vq75*JTzhGKCkQQ4Fk zVGkmS<%HN%+zl-j|A$NMVpKsP*VeP~vx$ibkXjBjP;qqXR5@0%bPMWZspH3juCMtL zbqnpeTt-8h(NeZ&$VpV%m z4-#P*Glrgb|1B>+^f7RGubv^KHB^l zd#(EbsM1gM+%`{pDvOvyS&LdcuyMWSRr?uz1{|{KbmXp%t*ZxYP)=IkL${DSC{~bm z$ivKc&b+<3IvpaGNnsbmOG}+E|FSbiexDCf4^a9rpke&?%SQi7>A&-K|FLW|Dt$_i zx^_qv(N|C&`Uu1tEnZ0*Ca>6o#W5_VzawHRT~t!?K4FJPBT&@Rk~+kJH~D>VcBm|Y z#P=p2P?ehh3`hjOpIDsbL!H1D>nn|vK6xgWFR;tl(()9~&Zh~eTZks!FLSX~Gnqm@ zxL2{W2nSBU!D@qFBV>qBd53g&Qa1`Z-4c944zc;#s47_HJqS`HPoqhI_!dlT67_*2 z%JzGG&286W^vupA>gYJ))LB4V%|3F&F_$s1e-gw6ljYd8L#a}@ZWLuAof^8;17G$x ziK!t(-rVkLGI$8^g{>fN@rjSb8h$?1kaZutAwERTuAKM!(=GD~Q4ws1cMtV7V&S1r zHKdD>R=Uuo@n-7NS%tYq>GsR89!MzPK_)Z76~>wSx96D0oiB?pp$x}-GU{z{oXTPg z^+imHG7ZfIdIt@EAHH{MvbvPMy#^1M+lS~5tBM%>+NpJ7owx7SJKlWJ`03z&FKM4P zl+H17#~#dtcZA%jQf7G9m?v^4+qHJL@hNPa^Rd-Kwda1>{P}0hnYPNXlXHrQR3aln zUueKL!rEg7wpX5Qm(ah?{rlH>=C=U$pa*aQf6K3I{AYU*vvvZko*DjAFwK`Aj{scw z==cTu$rg*_M2LbZO%QiqvW|=TB2x;5vD3da$C_G^)8;;y1hi5h_4S$iQ;ZYNqv!Dn*JnNSK?Uy31 z+n6>%sP5pmjBfDq+pb}3EN7!OO=J))JmM<+zj8hz;jx7N9PXhSNnmRE(P&rsd_(RW z9ts-NO6Zj7F4?J1NAL|w>7*ufhrvmXTTt(g7S*!#J>xSs=?ytNR8l$_gW++c)Q`4J z5{U=d^);JI{8;8??W1$VfMsnZ@l3^~FrygQWDzO%EImY+l>yWwI~UnLwY}G;L&z)% zM8tQGLjrI)K6HiVZ&9Z3S?47I^a(Y(BN0cYj;24IJKsmo==&b~ysFY16RDo=CL9cn zZyX&$JpbZLdSHF6ssOf=3GgNVsqOs1&izle6E5HVYjd&vnF{h}74cHqGZre|0_*U{7_~WadKvlCWvnHgnZ4*~81c^a_4Ol%qJ|~p5?ix5U~O>`k87oN^Nntg zl#gJM%6AdBt;t0(hoR#1h9~}Vxu3=>WP8)#|N&oSHaUvM6{U$ zBBP0~%iQearM=^)Rg45I@Ii4%6>|Nez`IPzL9e4py_OM0tIMUioUV^k*?AkFtSR^e z&xeAD6|!Y}KcBE~r{qbTx@Mw%cq$!&D?N5oKS+*o-oA3mb147Bs|Y)d5Io;afJK%! zsRyapPPw-ra1@_|xPkDAOfDnuo)tDfQkpK^JFJgS71(#7hJe;~d}2+^9(dmKy5X9gNE|c0p?= zQ^1^>VSX zvIMY&g8#yg`~kN8CtHYDSp9_`^q5rnK8GIa)Q-=m6hK>y6{00CI(G+^Y#7r-?6hFV z2YKGTSjuxM2%J}(ktbg!hWFz+%Sxy7Hh-);*64wy-{6-JoeDTCJj8JVXZAl!F zxcC`x&l_A5utdyVdCJ~!*_d&~wK#G((%4e=NJy^Id z3{pwrAqIJPQ3i3#xZDi%8@^|Jc^`g0YC4CDh(MnV4Cn;0!7Xp&a!G_M7(I?fcN1a&bh5w9&OS2c+`n=-jEx%6j&j|+3tKzL;t2B9pFRcpQ`g6=~%VQlLTsH^pxFa;ApaY}=1;mYp@%_H=1J=C2(TbQ9 zLNg(a&^OhGM*S125S2|L(Yex~=2kc@W2Ou&HI$-Up@Zpd1ciZU3tT6pw8IRMrMxp} zq?3m0Qt;EHd+HOFt2(8|77Qc-N*5W;6Nj{}q51iX)yq|hA z&>u{?&W2a0No^_knf+>SyCNYO2WxPEPB5U?kUvqAM7q+W?#ZKk2?^!9*23o5+nni} z8`~OC67wBBIM7k7sN8{`qeie^sR}}eU$al$qTacHwF`?r)QP=&S$N%O#OY&ngEhI? zTDX}kxR20@LEj!FQWYuH1>&9RH{?i$(5vFU-dw2PU`Po;z{YC&gleN=r3&bT)7Dt}Zwze265J+mPo9N~8%o?i_B|!_gJqoAUYoB+N4k&CqR+2WF)0b12 zaik}n#OVaU+N_Kn>~SNe^7pt7cJ5wF*VSvRVl`AM!aa97#b7xi^ck_BFuKcb0{b|x zEPQL|Fb3_}Nr!AlAqJgFJ0v2&o_nMc?;eJ_J|vdfKwZGk;G?b1dhdD$QwCXEvnMWF z5c$4Y5*_8>yg(`iUK=p$6lFugL%}ENX{-MV!o^ zs45A}Dbs1j1Pv^-gEIGR@Mc;%@Ba&g2?N${pB5l~AAtD(wx;-(;ureuW&fds|5+OC z7qwg|aYUGslEo%Kwjv<5U~Y=-V~+6K_0B1A1{@{9S4DNYOD$w$+EgTWNG-a%@j(s%j(FJKNM9y3B9*3gTsuNG8Oays4?^gP_ ztZ8#v{9(aEL98E57P7>mq&e(lrVV)Q6f?hPCfhF+Wn_8F=b0F&b5iGS1|Ml1F3-Z! z_z=kgY*GZ1)+mw1WaE)^jLQz|m1rQ>5Cy`*Ype}#($vfDQwJ;?on0LDE`3Umk>2?r z!uCm_6Z%7BX>XF!cxo89Ov?tT5dW52y%;@p8*i1(pB*aY7eNOofFd~m3-9&&JNO5N zHoE%PGGm}KZ@(C|RbC6i6bU3z9I#@Ep{_uXyR;+@7X}3CuU*C&(vM$8j9=g0W*_bS za(aBbT71J|1cjtI%Z^uDPH?Vrl!!^7CVAE8um=>^RS&muJEJU^!9)zoL@LX+@0IIV zFlC;{sS{04s>>`)@z$b$!wjsdmkY8Xm>fa>*d{q8*GKF=cLAH>ydvQ@a8%J)j1%`p zkm$+q7iRnUrLeM}>`P^AEtZrmC|hpre27mFcfcN-Z!2L7V@_gu9#Lb8(_`88BTlao zj&Zpf_pr$|x#6`4+~&TF+EWs>8n=ro4((?@6S~#CCPS%bG~HmOqyu7T->HiqbtYT3 zhP;24aA~{oXH0;ES^f(N|B4L%Z0J$^zm6ve-Twy4$N}tH$@8xeeJt{=tpI0|)AdtAm+K=ehZL{!SU^J_cDf+B7D1F-#Fe;-S{~j(Jr!orfwm$%{o@@cp=^ z=9jM_qMI_r39rU$ZwQ<$w-jg0aGFik)SSXZ2@19LgL>==nB}cj(J*ywf`f6ue4H|5 z#A3kc{?Z9zg!_=jr~XN6$RFz?|0;e@2XW@A77zT$gi3z#60o?KqZA8*-eFsj!o5?p zS`O3?z(ph1O@^yDS_11ElXG%GNmU1i;hc{3Eg6}NJgREdfiGzF`QU?8wci@FtpsBx z`ZzIrZ}l<54sT!X&+L#o$7H@Jv#cV*MZ?>01;ps0;5g`TXDqS(S>jjwutK5$iN^yZ z&hZ~cq;I_eI|&GPqd*aWOp z@UO^NuRh*Pu-!i0pS6j1)$>1LH)>ki?+-Se zYw!>!gevS{R%3L9o~@qJ{L(^LAGFjQwV{pm-oUXU!i{>e&BxVCoBR?(A6>2Pc|4^6 zX|Cn1AjkPdZ*;8?_1qsX<*~Oh)iq}2H&>LKB$fFTP0Rys#}XC~?MhmH1G}SN6Hr*- zRh>-j@Fb^EL<+t1L&_x_lY*Fzp?{*>6u#~=tKLX8-uzr7lX?rIH$)WR2J>xzf59Wv z=~n#+`~fArc~wI56C7C2yyEFOAl8qI+~#fBc0p|VvxBRw5&&4q~<&Y zdu@zxy-N$W>Of+P5}zq?j6r{g z4`1AES5qvDYn_h$Zx=P?5$IofmRKpOlN~jFM1nG=pkS;JR%G>!YqTv9srp576et;bB zyBApb;4>6EZLpcIwmA+Hs}3gLSgFpjWIfc#Dc@64@7oP7L_dW-tc@2{$G7}A}_h_JHRQt0c881 z=H*Ia|M1*VqrVIFDb&Xr`Aa;)kZ@GWj*tZ8T}~-u{9uGRkEW0`T&Tw)Wq7H2?UFqzzy>+00E(-|`<^ zhjLOfzg5aAk~?6*wAaQx`GW2Qp~&PAGKMYb3H9fe>((UkSDWhsV4VVOmfFS}6K(ee zg2{T~SyGgHDTczN460MYsb{qWbGL9|i&!_&hs8N_13fSu*+bC^K4U96N-6#636A`h z6nN?TU>x;zRTRhEcG3&iI8S6&1@tCvF^CO_p7RaTYvnct7ih%o-xm2;VVyfYYDQ#}RzrIyoY%5pX5jPH!BSSa1a-z+Un+`rQFpBS^8C96c7= zyS_2>Y(&!ce|yA`F5ut1K^VSm(3v3XIaI4sr}dS1P)ZL!+%-c4ze#^~|6bL&_x(1I z%L`-QK_)zkLs@B)>U4+(Os9Sa#bNu~VYkzv$6o+`1+YG)@c?z90UC6C|CZhSru9Fo z>rVr}f3!E`Ln^L~ck)442y>Y8!`+A^a7RX*(48A y49DNu!knx&jJ0rbcR<7TY6 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�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 this) { * method will not all return the same set. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { @@ -462,7 +462,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { @@ -516,7 +516,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public abstract @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 8ad2bb07f65c..41ebc64a4546 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -203,7 +203,7 @@ private int newCapacity(int needed, int jump) { * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */ - public @Modifiable @IteratorPreservesRemove ArrayDeque() { + public @Modifiable @IteratorPolyShrink ArrayDeque() { elements = new Object[16 + 1]; } @@ -213,7 +213,7 @@ private int newCapacity(int needed, int jump) { * * @param numElements lower bound on initial capacity of the deque */ - public @Modifiable @IteratorPreservesRemove ArrayDeque(@NonNegative int numElements) { + public @Modifiable @IteratorPolyShrink ArrayDeque(@NonNegative int numElements) { elements = new Object[(numElements < 1) ? 1 : (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : @@ -230,7 +230,7 @@ private int newCapacity(int needed, int jump) { * @param c the collection whose elements are to be placed into the deque * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { this(c.size()); copyElements(c); } @@ -1214,7 +1214,7 @@ private T[] toArray(Class klazz) { * @return a copy of this deque */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove ArrayDeque clone(@GuardSatisfied ArrayDeque this) { + public @Modifiable @IteratorPolyShrink ArrayDeque clone(@GuardSatisfied ArrayDeque this) { try { @SuppressWarnings("unchecked") ArrayDeque result = (ArrayDeque) super.clone(); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index b46df72d0b8e..8700715258e0 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -183,7 +183,7 @@ public class ArrayList extends AbstractList * is negative */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove ArrayList(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyShrink ArrayList(@NonNegative int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { @@ -198,7 +198,7 @@ public class ArrayList extends AbstractList * Constructs an empty list with an initial capacity of ten. */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove ArrayList() { + public @Modifiable @IteratorPolyShrink ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } @@ -211,7 +211,7 @@ public class ArrayList extends AbstractList * @throws NullPointerException if the specified collection is null */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { @@ -385,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove clone(@GuardSatisfied ArrayList this) { + public @Modifiable @IteratorPolyShrink clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index b4d7af5e642f..2c5f9817593f 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -3087,7 +3087,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - @IteratorPreservesRemove + @IteratorPolyShrink public Set keySet() { synchronized (mutex) { if (keySet==null) @@ -3097,7 +3097,7 @@ public Set keySet() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { synchronized (mutex) { if (entrySet==null) @@ -3106,7 +3106,7 @@ public Set> entrySet() { } } - @IteratorPreservesRemove + @IteratorPolyShrink public Collection values() { synchronized (mutex) { if (values==null) @@ -3397,13 +3397,13 @@ public NavigableMap descendingMap() { } } - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet navigableKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); @@ -3411,7 +3411,7 @@ public NavigableSet navigableKeySet() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet descendingKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); @@ -4191,9 +4191,9 @@ private String badValueMsg(Object value) { public V get(Object key) { return m.get(key); } public V remove(Object key) { return m.remove(key); } public void clear() { m.clear(); } - @IteratorPreservesRemove + @IteratorPolyShrink public Set keySet() { return m.keySet(); } - @IteratorPreservesRemove + @IteratorPolyShrink public Collection values() { return m.values(); } public boolean equals(Object o) { return o == this || m.equals(o); } public int hashCode() { return m.hashCode(); } @@ -4229,7 +4229,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); @@ -4722,19 +4722,19 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet navigableKeySet() { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet descendingKeySet() { return checkedNavigableSet(nm.descendingKeySet(), keyType); } @@ -6059,7 +6059,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) { * @see Enumeration * @see ArrayList */ - public static @Modifiable @IteratorPreservesRemove ArrayList list(Enumeration e) { + public static @Modifiable @IteratorPolyShrink ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 18776e7b887b..47338e12beb1 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -413,7 +413,7 @@ public void clear(@Shrinkable EnumMap this) { * * @return a set view of the keys contained in this enum map */ - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { Set ks = keySet; if (ks == null) { @@ -457,7 +457,7 @@ public void clear(@Shrinkable KeySet this) { * * @return a collection view of the values contained in this map */ - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { Collection vs = values; if (vs == null) { @@ -508,7 +508,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index a2f1e91bff50..a506f75b72ca 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -104,7 +104,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ final transient Enum[] universe; - @Modifiable @IteratorPreservesRemove EnumSet(ClasselementType, Enum[] universe) { + @Modifiable @IteratorPolyShrink EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } @@ -118,7 +118,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An empty enum set of the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPreservesRemove EnumSet noneOf(Class elementType) { + public static > @Modifiable @IteratorPolyShrink EnumSet noneOf(Class elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); @@ -139,7 +139,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An enum set containing all the elements in the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPreservesRemove EnumSet allOf(Class elementType) { + public static > @Modifiable @IteratorPolyShrink EnumSet allOf(Class elementType) { EnumSet result = noneOf(elementType); result.addAll(); return result; @@ -161,7 +161,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return A copy of the specified enum set. * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable @IteratorPreservesRemove EnumSet copyOf(EnumSet s) { + public static > @Modifiable @IteratorPolyShrink EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -179,7 +179,7 @@ public abstract sealed class EnumSet> extends AbstractSet * {@code EnumSet} instance and contains no elements * @throws NullPointerException if {@code c} is null */ - public static > @Modifiable @IteratorPreservesRemove EnumSet copyOf(Collection c) { + public static > @Modifiable @IteratorPolyShrink EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); } else { @@ -204,7 +204,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return The complement of the specified set in this set * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable @IteratorPreservesRemove EnumSet complementOf(EnumSet s) { + public static > @Modifiable @IteratorPolyShrink EnumSet complementOf(EnumSet s) { EnumSet result = copyOf(s); result.complement(); return result; @@ -224,7 +224,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code e} is null * @return an enum set initially containing the specified element */ - public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e) { + public static > @Modifiable @IteratorPolyShrink EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); return result; @@ -245,7 +245,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2) { + public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -268,7 +268,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2, E e3) { + public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -293,7 +293,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2, E e3, E e4) { + public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -320,7 +320,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPreservesRemove EnumSet of(E e1, E e2, E e3, E e4, + public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2, E e3, E e4, E e5) { EnumSet result = noneOf(e1.getDeclaringClass()); @@ -347,7 +347,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SafeVarargs - public static > @Modifiable @IteratorPreservesRemove EnumSet of(E first, E... rest) { + public static > @Modifiable @IteratorPolyShrink EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) @@ -369,7 +369,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ - public static > @Modifiable @IteratorPreservesRemove EnumSet range(E from, E to) { + public static > @Modifiable @IteratorPolyShrink EnumSet range(E from, E to) { if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to); EnumSet result = noneOf(from.getDeclaringClass()); @@ -391,7 +391,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SuppressWarnings("unchecked") @DoesNotUnrefineReceiver("modifiability") - public @Modifiable @IteratorPreservesRemove EnumSet clone() { + public @Modifiable @IteratorPolyShrink EnumSet clone() { try { return (EnumSet) super.clone(); } catch(CloneNotSupportedException e) { diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 3cc84e08d357..5844a7ac800b 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -953,7 +953,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { @@ -1092,7 +1092,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { @@ -1159,7 +1159,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index c0c2351a3ea9..7be9d3d37a41 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -126,7 +126,7 @@ public class HashSet * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPreservesRemove HashSet() { + public @Modifiable @IteratorPolyShrink HashSet() { map = new HashMap<>(); } @@ -139,7 +139,7 @@ public class HashSet * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -157,7 +157,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPreservesRemove HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPolyShrink HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -173,7 +173,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPreservesRemove HashSet(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyShrink HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -190,7 +190,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @Modifiable @IteratorPreservesRemove HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable @IteratorPolyShrink HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } @@ -294,7 +294,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied HashSet this) { + public @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied HashSet this) { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 22fe89b652b4..03538b97454b 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -703,7 +703,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); @@ -751,7 +751,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); @@ -840,7 +840,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 55c482d9f6ba..d60fdf0a4b6c 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1035,7 +1035,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { @@ -1152,7 +1152,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { @@ -1269,7 +1269,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index a40c2b422b6e..5f9952db62aa 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -655,7 +655,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { return sequencedKeySet(); } @@ -816,7 +816,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { return sequencedValues(); } @@ -932,7 +932,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -1232,17 +1232,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } - @IteratorPreservesRemove + @IteratorPolyShrink public Set keySet() { return base.sequencedKeySet().reversed(); } - @IteratorPreservesRemove + @IteratorPolyShrink public Collection values() { return base.sequencedValues().reversed(); } - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 5a63bb93dac3..725fdabd7880 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; @@ -154,7 +154,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPreservesRemove LinkedHashSet(int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPolyShrink LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } @@ -170,7 +170,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPreservesRemove LinkedHashSet(int initialCapacity) { + public @Modifiable @IteratorPolyShrink LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } @@ -178,7 +178,7 @@ public class LinkedHashSet * Constructs a new, empty linked hash set with the default initial * capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPreservesRemove LinkedHashSet() { + public @Modifiable @IteratorPolyShrink LinkedHashSet() { super(16, .75f, true); } @@ -192,7 +192,7 @@ public class LinkedHashSet * this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreservesRemove LinkedHashSet(Collection c) { + public @Modifiable @IteratorPolyShrink LinkedHashSet(Collection c) { super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true); addAll(c); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index 3900c58d8984..57fc993eec14 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -144,7 +144,7 @@ void dataStructureInvariants() { /** * Constructs an empty list. */ - public @Modifiable @IteratorPreservesRemove LinkedList() { + public @Modifiable @IteratorPolyShrink LinkedList() { } /** @@ -155,7 +155,7 @@ void dataStructureInvariants() { * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -1113,7 +1113,7 @@ private LinkedList superClone() { * @return a shallow copy of this {@code LinkedList} instance */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied LinkedList this) { + public @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied LinkedList this) { LinkedList clone = superClone(); // Put clone into "virgin" state diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 10cbe9518145..0c2f1f039d3c 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -404,7 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** @@ -423,7 +423,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** @@ -443,7 +443,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index ae81ad847d46..b5bbcf9c16a9 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,7 +36,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -313,7 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); /** @@ -331,7 +331,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); /** diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 7c5dd80649c1..71957f343a2c 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -152,7 +152,7 @@ public class PriorityQueue extends AbstractQueue * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPreservesRemove PriorityQueue() { + public @Modifiable @IteratorPolyShrink PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -165,7 +165,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPreservesRemove PriorityQueue(@Positive int initialCapacity) { + public @Modifiable @IteratorPolyShrink PriorityQueue(@Positive int initialCapacity) { this(initialCapacity, null); } @@ -178,7 +178,7 @@ public class PriorityQueue extends AbstractQueue * natural ordering} of the elements will be used. * @since 1.8 */ - public @Modifiable @IteratorPreservesRemove PriorityQueue(Comparator comparator) { + public @Modifiable @IteratorPolyShrink PriorityQueue(Comparator comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); } @@ -193,7 +193,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 */ - public @Modifiable @IteratorPreservesRemove PriorityQueue(@Positive int initialCapacity, + public @Modifiable @IteratorPolyShrink PriorityQueue(@Positive int initialCapacity, Comparator comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility @@ -219,7 +219,7 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { if (c instanceof SortedSet) { SortedSet ss = (SortedSet) c; this.comparator = (Comparator) ss.comparator(); @@ -250,7 +250,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified priority queue or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove PriorityQueue(PriorityQueue c) { + public @Modifiable @IteratorPolyShrink PriorityQueue(PriorityQueue c) { this.comparator = (Comparator) c.comparator(); initFromPriorityQueue(c); } @@ -268,7 +268,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove PriorityQueue(SortedSet c) { + public @Modifiable @IteratorPolyShrink PriorityQueue(SortedSet c) { this.comparator = (Comparator) c.comparator(); initElementsFromCollection(c); } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index bbbf861a973f..c43ca8edbd40 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -1395,20 +1395,20 @@ public synchronized String toString() { } @Override - @IteratorPreservesRemove + @IteratorPolyShrink public Set<@KeyFor("this") Object> keySet() { return Collections.synchronizedSet(map.keySet(), this); } @Override - @IteratorPreservesRemove + @IteratorPolyShrink public Collection values() { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 442d1b279529..504a43e984a8 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -25,7 +25,7 @@ package java.util; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.dataflow.qual.Pure; /** @@ -98,7 +98,7 @@ public int size() { return base.size(); } - @IteratorPreservesRemove + @IteratorPolyShrink public Set keySet() { return new AbstractSet<>() { // inherit add(), which throws UOE @@ -110,7 +110,7 @@ public Set keySet() { }; } - @IteratorPreservesRemove + @IteratorPolyShrink public Collection values() { return new AbstractCollection<>() { // inherit add(), which throws UOE @@ -122,7 +122,7 @@ public Collection values() { }; } - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { return new AbstractSet<>() { // inherit add(), which throws UOE @@ -398,7 +398,7 @@ public String toString() { return ReverseOrderSortedMapView.toString(this, entryIterator()); } - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { return new AbstractSet<>() { public Iterator> iterator() { diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index c12b7899224d..1b3bba1cdbd5 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -265,7 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); /** @@ -287,7 +287,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); /** @@ -309,7 +309,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 30f26e82df35..02db44159d67 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -67,7 +67,7 @@ public class Stack extends Vector { /** * Creates an empty Stack. */ - public @Modifiable @IteratorPreservesRemove Stack() { + public @Modifiable @IteratorPolyShrink Stack() { } /** diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index bfc0691ef3cb..07690bc38ed1 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1190,7 +1190,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @DoesNotUnrefineReceiver("modifiability") - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1199,7 +1199,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); @@ -1209,7 +1209,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1235,7 +1235,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { @@ -1268,7 +1268,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); @@ -2059,20 +2059,20 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public final NavigableSet navigableKeySet() { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } - @IteratorPreservesRemove + @IteratorPolyShrink public final Set keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } @@ -2399,7 +2399,7 @@ public Iterator> iterator() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); @@ -2493,7 +2493,7 @@ public Iterator> iterator() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index acf9d6945e74..ef75d358475c 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -131,7 +131,7 @@ public class TreeSet extends AbstractSet /** * Constructs a set backed by the specified navigable map. */ - @Modifiable @IteratorPreservesRemove TreeSet(NavigableMap m) { + @Modifiable @IteratorPolyShrink TreeSet(NavigableMap m) { this.m = m; } @@ -148,7 +148,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable @IteratorPreservesRemove TreeSet() { + public @Modifiable @IteratorPolyShrink TreeSet() { this(new TreeMap<>()); } @@ -165,7 +165,7 @@ public class TreeSet extends AbstractSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPreservesRemove TreeSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyShrink TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -183,7 +183,7 @@ public class TreeSet extends AbstractSet * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -553,7 +553,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied TreeSet this) { + public @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 136923ca3c34..3c1b26f31194 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -167,7 +167,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPreservesRemove Vector(@NonNegative int initialCapacity, int capacityIncrement) { + public @Modifiable @IteratorPolyShrink Vector(@NonNegative int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ @@ -184,7 +184,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPreservesRemove Vector(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyShrink Vector(@NonNegative int initialCapacity) { this(initialCapacity, 0); } @@ -193,7 +193,7 @@ public class Vector * has size {@code 10} and its standard capacity increment is * zero. */ - public @Modifiable @IteratorPreservesRemove Vector() { + public @Modifiable @IteratorPolyShrink Vector() { this(10); } @@ -207,7 +207,7 @@ public class Vector * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public @Modifiable @IteratorPreservesRemove @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrink @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); elementCount = a.length; if (c.getClass() == ArrayList.class) { @@ -712,7 +712,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @return a clone of this vector */ @SideEffectFree - public synchronized @Modifiable @IteratorPreservesRemove Object clone(@GuardSatisfied Vector this) { + public synchronized @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied Vector this) { try { @SuppressWarnings("unchecked") Vector v = (Vector) super.clone(); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 39c48997667d..71da4ded8434 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -922,7 +922,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { @@ -984,7 +984,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { @@ -1037,7 +1037,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); 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 9f2f6c0b370e..8b3ec37eb656 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -276,7 +276,7 @@ void removeAt(final int removeIndex) { * @param capacity the capacity of this queue * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPreservesRemove ArrayBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyShrink ArrayBlockingQueue(int capacity) { this(capacity, false); } @@ -290,7 +290,7 @@ void removeAt(final int removeIndex) { * if {@code false} the access order is unspecified. * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPreservesRemove ArrayBlockingQueue(int capacity, boolean fair) { + public @Modifiable @IteratorPolyShrink ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; @@ -315,7 +315,7 @@ void removeAt(final int removeIndex) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove ArrayBlockingQueue(int capacity, boolean fair, + public @Modifiable @IteratorPolyShrink ArrayBlockingQueue(int capacity, boolean fair, Collection c) { this(capacity, fair); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index a7a5fd755fd5..7616cc460089 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1280,7 +1280,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public KeySetView<@KeyFor({"this"}) K,V> keySet() { KeySetView ks; if ((ks = keySet) != null) return ks; @@ -1306,7 +1306,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; @@ -1331,7 +1331,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; @@ -2287,7 +2287,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @return the set view * @throws NullPointerException if the mappedValue is null */ - @IteratorPreservesRemove + @IteratorPolyShrink public KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 37494772d50f..f7c3ccf7e476 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -793,7 +793,7 @@ private E screenNullResult(@NonNull E v) { /** * Constructs an empty deque. */ - public @Modifiable @IteratorPreservesRemove ConcurrentLinkedDeque() { + public @Modifiable @IteratorPolyShrink ConcurrentLinkedDeque() { head = tail = new Node(); } @@ -806,7 +806,7 @@ private E screenNullResult(@NonNull E v) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove ConcurrentLinkedDeque(Collection c) { + public @Modifiable @IteratorPolyShrink ConcurrentLinkedDeque(Collection c) { // Copy c into a private chain of Nodes Node h = null, t = null; for (E e : c) { diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 43e6e57de2d4..a424fe252d47 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -265,7 +265,7 @@ boolean casItem(E cmp, E val) { /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public @Modifiable @IteratorPreservesRemove ConcurrentLinkedQueue() { + public @Modifiable @IteratorPolyShrink ConcurrentLinkedQueue() { head = tail = new Node(); } @@ -278,7 +278,7 @@ boolean casItem(E cmp, E val) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove ConcurrentLinkedQueue(Collection c) { + public @Modifiable @IteratorPolyShrink ConcurrentLinkedQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index c0dbdc03365b..c4cb851d62b7 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -147,7 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); /** @@ -168,7 +168,7 @@ public interface ConcurrentNavigableMap * * @return a navigable set view of the keys in this map */ - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); /** @@ -188,6 +188,6 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index ea3ea601d713..0058e4e7a7e4 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; @@ -1650,7 +1650,7 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1658,7 +1658,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1684,7 +1684,7 @@ else if (doRemove(key, v) != null) *

The view's iterators and spliterators are * weakly consistent. */ - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; @@ -1719,7 +1719,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; @@ -1735,7 +1735,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3016,7 +3016,7 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet keySet() { KeySet ks; if ((ks = keySetView) != null) return ks; @@ -3024,14 +3024,14 @@ public NavigableSet keySet() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet navigableKeySet() { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } - @IteratorPreservesRemove + @IteratorPolyShrink public Collection values() { Values vs; if ((vs = valuesView) != null) return vs; @@ -3039,7 +3039,7 @@ public Collection values() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public Set> entrySet() { EntrySet es; if ((es = entrySetView) != null) return es; @@ -3047,7 +3047,7 @@ public Set> entrySet() { } @SideEffectFree - @IteratorPreservesRemove + @IteratorPolyShrink public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 34b92aa3558e..0fb0ff395c85 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -132,7 +132,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet() { + public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -144,7 +144,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -159,7 +159,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(Collection c) { + public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -172,7 +172,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(SortedSet s) { + public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -180,7 +180,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -191,7 +191,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable @IteratorPreservesRemove ConcurrentSkipListSet clone() { + public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 32be820f1a5f..b91d904b7fc1 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -154,7 +154,7 @@ public class DelayQueue extends AbstractQueue /** * Creates a new {@code DelayQueue} that is initially empty. */ - public @Modifiable @IteratorPreservesRemove DelayQueue() {} + public @Modifiable @IteratorPolyShrink DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -164,7 +164,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove DelayQueue(Collection c) { + public @Modifiable @IteratorPolyShrink DelayQueue(Collection c) { this.addAll(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 93938b94b644..c1c73012e080 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -194,7 +194,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPreservesRemove LinkedBlockingDeque() { + public @Modifiable @IteratorPolyShrink LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -204,7 +204,7 @@ static final class Node { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public @Modifiable @IteratorPreservesRemove LinkedBlockingDeque(int capacity) { + public @Modifiable @IteratorPolyShrink LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -219,7 +219,7 @@ static final class Node { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove LinkedBlockingDeque(Collection c) { + public @Modifiable @IteratorPolyShrink LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } 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 4e9feb1b770c..4983400e1ab9 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -264,7 +264,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPreservesRemove LinkedBlockingQueue() { + public @Modifiable @IteratorPolyShrink LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -275,7 +275,7 @@ void fullyUnlock() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public @Modifiable @IteratorPreservesRemove LinkedBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyShrink LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -291,7 +291,7 @@ void fullyUnlock() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove LinkedBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyShrink LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 6b851777c853..fa885e110bec 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1179,7 +1179,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public @Modifiable @IteratorPreservesRemove LinkedTransferQueue() { + public @Modifiable @IteratorPolyShrink LinkedTransferQueue() { head = tail = new Node(); } @@ -1192,7 +1192,7 @@ else if (s == n) // stale * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove LinkedTransferQueue(Collection c) { + public @Modifiable @IteratorPolyShrink LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(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 d84edb46b233..9cdf7500b254 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPreservesRemove; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -210,7 +210,7 @@ public class PriorityBlockingQueue extends AbstractQueue * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue() { + public @Modifiable @IteratorPolyShrink PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -223,7 +223,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue(int initialCapacity) { + public @Modifiable @IteratorPolyShrink PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -239,7 +239,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue(int initialCapacity, + public @Modifiable @IteratorPolyShrink PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -263,7 +263,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPreservesRemove PriorityBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyShrink PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java index 11990235099e..3fecd1d288b1 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/IndexOrHigh.java @@ -33,6 +33,11 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) public @interface IndexOrHigh { - /** The annotated expression is a valid index for, or is equal to the length of, each sequence. */ + /** + * The annotated expression is a valid index for, or is equal to the length of, each sequence. + * + * @return sequences that the annotated expression is a valid index for or is equal to the length + * of + */ String[] value(); } diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java new file mode 100644 index 000000000000..164a8f8d1308 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * If a collection's type is {@code @IteratorPolyShrink}, then its {@code iterator()} method + * preserves the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has + * type {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any + * collection whose type is {@code @UnknownIteratorPolyShrink}, its iterator is always + * {@code @Unshrinkable}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownIteratorPolyShrink.class) +public @interface IteratorPolyShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java index caa15121e762..537f47bfada7 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -7,19 +7,13 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @Growable @Shrinkable @Replaceable}. Calling grow, shrink, and - * replace operations such as {@code add}, {@code remove}, {@code set}, etc. on this collection will - * not result in throwing {@link UnsupportedOperationException}. + * Convenience alias usually meaning {@code @Growable @Shrinkable @Replaceable}. Calling a mutating + * operation (growing, shrinking, or replacing) on this collection will not result in throwing + * {@link UnsupportedOperationException}. * - *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @Growable @Shrinkable @Replaceable} on each annotated type. - * - *

Some Java types lack methods for certain kinds of mutation. For these types, the Modifiability Checker defaults - * them to {@code @Unknown}: - *

    {@code @Modifiable Iterator<>} is treated as {@code @UnknownGrow @Shrinkable @UnknownReplace Iterator}.
- *
    {@code @Modifiable Set<>} is treated as {@code @Growable @Shrinkable @UnknownReplace Set}.
- *
    {@code @Modifiable Queue<>} is treated as {@code @Growable @Shrinkable @UnknownReplace Queue}.
- *
    {@code Map.@Modifiable Entry<>} is treated as {@code @UnknownGrow @UnknownShrink @Replaceable List}.
+ *

As an exception, {@code @Modifiable} means {@code @Unknown*} if the type does not support a + * given category of operation; for example, {@Modifiable Iterator} means + * {@code @UnknownGrow @UnknownShrink @Replaceable Iterator}.) * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 73bc67261eb3..87345ae94317 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -4,14 +4,11 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @PolyGrow @PolyShrink @PolyReplace}. A polymorphic qualifier for + * Convenience alias meaning {@code @PolyGrow @PolyReplace @PolyShrink}. A polymorphic qualifier for * all three modifiability hierarchies. * - *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @PolyGrow @PolyShrink @PolyReplace} on each annotated type. - * - *

Use on methods that preserve or transfer modifiability — for example, {@code - * List.subList()}, {@code iterator()}, or {@code stream()}. + *

You should write {@code @PolyModifiable} on methods that preserve or transfer modifiability, + * such as {@code List.subList()}, {@code iterator()}, and {@code stream()}. * *

For example: * @@ -21,8 +18,9 @@ * } * * - * If the receiver is {@code @Unmodifiable}, the return is {@code @Unmodifiable}. If the receiver is - * {@code @Modifiable}, the return is {@code @Modifiable}. + * If the receiver type at a given call site is {@code @Unmodifiable}, the return type at that call + * site {@code @Unmodifiable}. If the receiver type is {@code @Modifiable}, the return type is + * {@code @Modifiable}. Likewise for growing and shrinking type qualifiers. * * @checker_framework.manual #modifiability-checker Modifiability Checker * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java index 3651620510c7..1275077f2023 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java @@ -7,8 +7,7 @@ import java.lang.annotation.Target; /** - * Indicates that the annotated method always throws {@link UnsupportedOperationException} when - * called. + * The annotated method always throws {@link UnsupportedOperationException} when called. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java new file mode 100644 index 000000000000..b74f7b26c438 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java @@ -0,0 +1,24 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * For the annotated collection, The return type of {@code iterator()} is {@code @Unshrinkable}. + * + *

This is the default qualifier for unannotated types. + * + * @see #IteratorPolyShrink + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({}) +@DefaultQualifierInHierarchy +public @interface UnknownIteratorPolyShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index 69aadab79673..56f430ac40ca 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -7,19 +7,13 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @Ungrowable @Unshrinkable @Unreplaceable}. Calling any mutating - * operation on this collection (growing, shrinking, or replacing) will throw {@link + * Convenience alias usually meaning {@code @Ungrowable @Unshrinkable @Unreplaceable}. Calling a + * mutating operation (growing, shrinking, or replacing) may throw {@link * UnsupportedOperationException}. * - *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @Ungrowable @Unshrinkable @Unreplaceable} on each annotated type. - * - *

Some Java types lack methods for certain kinds of mutation. For these types, the Modifiability Checker defaults - * them to {@code @Unknown}: - *

    {@code @Unmodifiable Iterator<>} is treated as {@code @UnknownGrow @Unshrinkable @UnknownReplace Iterator}.
- *
    {@code @Unmodifiable Set<>} is treated as {@code @Ungrowable @Unshrinkable @UnknownReplace Set}.
- *
    {@code @Unmodifiable Queue<>} is treated as {@code @Ungrowable @Unshrinkable @UnknownReplace Queue}.
- *
    {@code Map.@Unmodifiable Entry<>} is treated as {@code @UnknownGrow @UnknownShrink @Unreplaceable List}.
+ *

As an exception, {@code @Unmodifiable} means {@code @Unknown*} if the type does not support a + * given category of operation; for example, {@Unmodifiable Iterator} means + * {@code @UnknownGrow @UnknownShrink @Unreplaceable Iterator}.) * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/NonLeaked.java b/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/NonLeaked.java index ad0b07366d57..5686d79b5b3d 100644 --- a/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/NonLeaked.java +++ b/src/java.base/share/classes/org/checkerframework/common/aliasing/qual/NonLeaked.java @@ -21,7 +21,7 @@ */ // This is a type qualifier because of a Checker Framework limitation (Issue 383), but its hierarchy -// is ignored. Once the stub parser gets updated to read non-type-qualifiers annotations on stub +// is ignored. Once the stub parser gets updated to store non-type-qualifier annotations from stub // files, this annotation won't be a type qualifier anymore. @Documented diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java b/src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java index 4eca89c86484..33e94710d019 100644 --- a/src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java +++ b/src/java.base/share/classes/org/checkerframework/framework/qual/DoesNotUnrefineReceiver.java @@ -15,9 +15,8 @@ * @checker_framework.manual #type-refinement-purity Side effects, determinism, purity, and * flow-sensitive analysis */ -// @InheritedAnnotation cannot be written here, because "dataflow" project cannot depend on -// "framework" project. @Documented +@InheritedAnnotation @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) public @interface DoesNotUnrefineReceiver { diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java b/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java index a3ab69c41550..ce2df1af281b 100644 --- a/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java +++ b/src/java.base/share/classes/org/checkerframework/framework/qual/PreconditionAnnotation.java @@ -43,7 +43,7 @@ * {@code @MinLen(2)} upon entry. * *


- *  {@literal @}RequiresMinLen(value = "field", targetValue = 2")
+ *  {@literal @}RequiresMinLen(value = "field", targetValue = 2)
  *  public char getThirdCharacter() {
  *    return field.charAt(2);
  *  }

From 53ba3e4173bbf333deb3aef0b0ebda2db593898d Mon Sep 17 00:00:00 2001
From: YukiYang31 
Date: Sat, 2 May 2026 17:21:49 -0700
Subject: [PATCH 068/119] fixed listIterator annotation

---
 src/java.base/share/classes/java/util/AbstractList.java     | 6 +++---
 .../share/classes/java/util/AbstractSequentialList.java     | 4 ++--
 src/java.base/share/classes/java/util/List.java             | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java
index ebc730d871f7..6fc9e1f15dc4 100644
--- a/src/java.base/share/classes/java/util/AbstractList.java
+++ b/src/java.base/share/classes/java/util/AbstractList.java
@@ -339,7 +339,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi
      * @return an iterator over the elements in this list in proper sequence
      */
     @SideEffectFree
-    public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) {
+    public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) {
         return new Itr();
     }
 
@@ -351,7 +351,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi
      *
      * @see #listIterator(int)
      */
-    public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) {
+    public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) {
         return listIterator(0);
     }
 
@@ -378,7 +378,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi
      *
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
-    public @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable AbstractList this, final @IndexOrHigh({"this"}) int index) {
+    public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this, final @IndexOrHigh({"this"}) int index) {
         rangeCheckForAdd(index);
 
         return new ListItr(index);
diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java
index 31c5e77a0b6d..8ad691322c4e 100644
--- a/src/java.base/share/classes/java/util/AbstractSequentialList.java
+++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java
@@ -255,7 +255,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractSequentialList this,
      * @return an iterator over the elements in this list (in proper sequence)
      */
     @SideEffectFree
-    public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractSequentialList this) {
+    public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractSequentialList this) {
         return listIterator();
     }
 
@@ -269,5 +269,5 @@ public boolean addAll(@Growable @GuardSatisfied AbstractSequentialList this,
      *         sequence)
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
-    public abstract @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable AbstractSequentialList this, int index);
+    public abstract @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink AbstractSequentialList this, int index);
 }
diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java
index 69bc34830f43..a15f9314a485 100644
--- a/src/java.base/share/classes/java/util/List.java
+++ b/src/java.base/share/classes/java/util/List.java
@@ -739,7 +739,7 @@ default void sort(@Replaceable List this, Comparator c) {
      * @return a list iterator over the elements in this list (in proper
      *         sequence)
      */
-    @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this);
+    @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this);
 
     /**
      * Returns a list iterator over the elements in this list (in proper
@@ -756,7 +756,7 @@ default void sort(@Replaceable List this, Comparator c) {
      * @throws IndexOutOfBoundsException if the index is out of range
      *         ({@code index < 0 || index > size()})
      */
-    @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index);
+    @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index);
 
     // View
 

From 4f7ffddf7e7cbd5144c94594bc26737da15a5fb1 Mon Sep 17 00:00:00 2001
From: YukiYang31 
Date: Sun, 3 May 2026 21:18:53 -0700
Subject: [PATCH 069/119] rename IteratorPolyShrink to IteratorPolyMod

---
 .../share/classes/java/util/AbstractMap.java  |  8 ++---
 .../share/classes/java/util/ArrayDeque.java   | 10 +++----
 .../share/classes/java/util/ArrayList.java    | 10 +++----
 .../share/classes/java/util/Collections.java  | 28 ++++++++---------
 .../share/classes/java/util/EnumMap.java      |  8 ++---
 .../share/classes/java/util/EnumSet.java      | 30 +++++++++----------
 .../share/classes/java/util/HashMap.java      |  8 ++---
 .../share/classes/java/util/HashSet.java      | 14 ++++-----
 .../share/classes/java/util/Hashtable.java    |  8 ++---
 .../classes/java/util/IdentityHashMap.java    |  8 ++---
 .../classes/java/util/LinkedHashMap.java      | 14 ++++-----
 .../classes/java/util/LinkedHashSet.java      | 10 +++----
 .../share/classes/java/util/LinkedList.java   |  8 ++---
 .../share/classes/java/util/Map.java          |  8 ++---
 .../share/classes/java/util/NavigableMap.java |  6 ++--
 .../classes/java/util/PriorityQueue.java      | 16 +++++-----
 .../share/classes/java/util/Properties.java   |  8 ++---
 .../java/util/ReverseOrderSortedMapView.java  | 10 +++----
 .../share/classes/java/util/SortedMap.java    |  8 ++---
 .../share/classes/java/util/Stack.java        |  4 +--
 .../share/classes/java/util/TreeMap.java      | 22 +++++++-------
 .../share/classes/java/util/TreeSet.java      | 14 ++++-----
 .../share/classes/java/util/Vector.java       | 12 ++++----
 .../share/classes/java/util/WeakHashMap.java  |  8 ++---
 .../util/concurrent/ArrayBlockingQueue.java   |  8 ++---
 .../util/concurrent/ConcurrentHashMap.java    | 10 +++----
 .../concurrent/ConcurrentLinkedDeque.java     |  6 ++--
 .../concurrent/ConcurrentLinkedQueue.java     |  6 ++--
 .../concurrent/ConcurrentNavigableMap.java    |  8 ++---
 .../concurrent/ConcurrentSkipListMap.java     | 22 +++++++-------
 .../concurrent/ConcurrentSkipListSet.java     | 14 ++++-----
 .../java/util/concurrent/DelayQueue.java      |  6 ++--
 .../util/concurrent/LinkedBlockingDeque.java  |  8 ++---
 .../util/concurrent/LinkedBlockingQueue.java  |  8 ++---
 .../util/concurrent/LinkedTransferQueue.java  |  6 ++--
 .../concurrent/PriorityBlockingQueue.java     | 10 +++----
 36 files changed, 196 insertions(+), 196 deletions(-)

diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java
index b60eb45c9ab4..b86bd2ff614f 100644
--- a/src/java.base/share/classes/java/util/AbstractMap.java
+++ b/src/java.base/share/classes/java/util/AbstractMap.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.lock.qual.ReleasesNoLocks;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.Growable;
 import org.checkerframework.checker.modifiability.qual.Replaceable;
@@ -391,7 +391,7 @@ public void clear(@Shrinkable @GuardSatisfied AbstractMap this) {
      * method will not all return the same set.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) {
         Set ks = keySet;
         if (ks == null) {
@@ -462,7 +462,7 @@ public boolean contains(@UnknownSignedness Object k) {
      * method will not all return the same collection.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) {
         Collection vals = values;
         if (vals == null) {
@@ -516,7 +516,7 @@ public boolean contains(@UnknownSignedness Object v) {
     }
 
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public abstract @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this);
 
 
diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java
index 41ebc64a4546..0a3f9864e14d 100644
--- a/src/java.base/share/classes/java/util/ArrayDeque.java
+++ b/src/java.base/share/classes/java/util/ArrayDeque.java
@@ -39,7 +39,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -203,7 +203,7 @@ private int newCapacity(int needed, int jump) {
      * Constructs an empty array deque with an initial capacity
      * sufficient to hold 16 elements.
      */
-    public @Modifiable @IteratorPolyShrink ArrayDeque() {
+    public @Modifiable @IteratorPolyMod ArrayDeque() {
         elements = new Object[16 + 1];
     }
 
@@ -213,7 +213,7 @@ private int newCapacity(int needed, int jump) {
      *
      * @param numElements lower bound on initial capacity of the deque
      */
-    public @Modifiable @IteratorPolyShrink ArrayDeque(@NonNegative int numElements) {
+    public @Modifiable @IteratorPolyMod ArrayDeque(@NonNegative int numElements) {
         elements =
             new Object[(numElements < 1) ? 1 :
                        (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE :
@@ -230,7 +230,7 @@ private int newCapacity(int needed, int jump) {
      * @param c the collection whose elements are to be placed into the deque
      * @throws NullPointerException if the specified collection is null
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) {
         this(c.size());
         copyElements(c);
     }
@@ -1214,7 +1214,7 @@ private  T[] toArray(Class klazz) {
      * @return a copy of this deque
      */
     @SideEffectFree
-    public @Modifiable @IteratorPolyShrink ArrayDeque clone(@GuardSatisfied ArrayDeque this) {
+    public @Modifiable @IteratorPolyMod ArrayDeque clone(@GuardSatisfied ArrayDeque this) {
         try {
             @SuppressWarnings("unchecked")
             ArrayDeque result = (ArrayDeque) super.clone();
diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java
index 8700715258e0..4ced6e5c85f1 100644
--- a/src/java.base/share/classes/java/util/ArrayList.java
+++ b/src/java.base/share/classes/java/util/ArrayList.java
@@ -31,7 +31,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Replaceable;
@@ -183,7 +183,7 @@ public class ArrayList extends AbstractList
      *         is negative
      */
     @SideEffectFree
-    public @Modifiable @IteratorPolyShrink ArrayList(@NonNegative int initialCapacity) {
+    public @Modifiable @IteratorPolyMod ArrayList(@NonNegative int initialCapacity) {
         if (initialCapacity > 0) {
             this.elementData = new Object[initialCapacity];
         } else if (initialCapacity == 0) {
@@ -198,7 +198,7 @@ public class ArrayList extends AbstractList
      * Constructs an empty list with an initial capacity of ten.
      */
     @SideEffectFree
-    public @Modifiable @IteratorPolyShrink ArrayList() {
+    public @Modifiable @IteratorPolyMod ArrayList() {
         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
     }
 
@@ -211,7 +211,7 @@ public class ArrayList extends AbstractList
      * @throws NullPointerException if the specified collection is null
      */
     @SideEffectFree
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) {
         Object[] a = c.toArray();
         if ((size = a.length) != 0) {
             if (c.getClass() == ArrayList.class) {
@@ -385,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int
      * @return a clone of this {@code ArrayList} instance
      */
     @SideEffectFree
-    public @Modifiable @IteratorPolyShrink clone(@GuardSatisfied ArrayList this) {
+    public @Modifiable @IteratorPolyMod clone(@GuardSatisfied ArrayList this) {
         try {
             ArrayList v = (ArrayList) super.clone();
             v.elementData = Arrays.copyOf(elementData, size);
diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java
index 2c5f9817593f..17e1efdd82c0 100644
--- a/src/java.base/share/classes/java/util/Collections.java
+++ b/src/java.base/share/classes/java/util/Collections.java
@@ -30,7 +30,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Replaceable;
@@ -3087,7 +3087,7 @@ public void clear() {
         private transient Set> entrySet;
         private transient Collection values;
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set keySet() {
             synchronized (mutex) {
                 if (keySet==null)
@@ -3097,7 +3097,7 @@ public Set keySet() {
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set> entrySet() {
             synchronized (mutex) {
                 if (entrySet==null)
@@ -3106,7 +3106,7 @@ public Set> entrySet() {
             }
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Collection values() {
             synchronized (mutex) {
                 if (values==null)
@@ -3397,13 +3397,13 @@ public NavigableMap descendingMap() {
             }
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet keySet() {
             return navigableKeySet();
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet navigableKeySet() {
             synchronized (mutex) {
                 return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex);
@@ -3411,7 +3411,7 @@ public NavigableSet navigableKeySet() {
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet descendingKeySet() {
             synchronized (mutex) {
                 return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex);
@@ -4191,9 +4191,9 @@ private String badValueMsg(Object value) {
         public V get(Object key)               { return m.get(key); }
         public V remove(Object key)            { return m.remove(key); }
         public void clear()                    { m.clear(); }
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set keySet()                 { return m.keySet(); }
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Collection values()          { return m.values(); }
         public boolean equals(Object o)        { return o == this || m.equals(o); }
         public int hashCode()                  { return m.hashCode(); }
@@ -4229,7 +4229,7 @@ public void putAll(Map t) {
         private transient Set> entrySet;
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set> entrySet() {
             if (entrySet==null)
                 entrySet = new CheckedEntrySet<>(m.entrySet(), valueType);
@@ -4722,19 +4722,19 @@ public NavigableMap descendingMap() {
             return checkedNavigableMap(nm.descendingMap(), keyType, valueType);
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet keySet() {
             return navigableKeySet();
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet navigableKeySet() {
             return checkedNavigableSet(nm.navigableKeySet(), keyType);
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet descendingKeySet() {
             return checkedNavigableSet(nm.descendingKeySet(), keyType);
         }
@@ -6059,7 +6059,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) {
      * @see Enumeration
      * @see ArrayList
      */
-    public static  @Modifiable @IteratorPolyShrink ArrayList list(Enumeration e) {
+    public static  @Modifiable @IteratorPolyMod ArrayList list(Enumeration e) {
         ArrayList l = new ArrayList<>();
         while (e.hasMoreElements())
             l.add(e.nextElement());
diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java
index 47338e12beb1..9e6f081bdd5e 100644
--- a/src/java.base/share/classes/java/util/EnumMap.java
+++ b/src/java.base/share/classes/java/util/EnumMap.java
@@ -29,7 +29,7 @@
 import org.checkerframework.checker.initialization.qual.UnknownInitialization;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -413,7 +413,7 @@ public void clear(@Shrinkable EnumMap this) {
      *
      * @return a set view of the keys contained in this enum map
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) {
         Set ks = keySet;
         if (ks == null) {
@@ -457,7 +457,7 @@ public void clear(@Shrinkable KeySet this) {
      *
      * @return a collection view of the values contained in this map
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) {
         Collection vs = values;
         if (vs == null) {
@@ -508,7 +508,7 @@ public void clear(@Shrinkable Values this) {
      * @return a set view of the mappings contained in this enum map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) {
         Set> es = entrySet;
         if (es != null)
diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java
index a506f75b72ca..eaed5d30f237 100644
--- a/src/java.base/share/classes/java/util/EnumSet.java
+++ b/src/java.base/share/classes/java/util/EnumSet.java
@@ -26,7 +26,7 @@
 package java.util;
 
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
 import org.checkerframework.checker.nullness.qual.Nullable;
@@ -104,7 +104,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      */
     final transient Enum[] universe;
 
-    @Modifiable @IteratorPolyShrink EnumSet(ClasselementType, Enum[] universe) {
+    @Modifiable @IteratorPolyMod EnumSet(ClasselementType, Enum[] universe) {
         this.elementType = elementType;
         this.universe    = universe;
     }
@@ -118,7 +118,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @return An empty enum set of the specified type.
      * @throws NullPointerException if {@code elementType} is null
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet noneOf(Class elementType) {
+    public static > @Modifiable @IteratorPolyMod EnumSet noneOf(Class elementType) {
         Enum[] universe = getUniverse(elementType);
         if (universe == null)
             throw new ClassCastException(elementType + " not an enum");
@@ -139,7 +139,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @return An enum set containing all the elements in the specified type.
      * @throws NullPointerException if {@code elementType} is null
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet allOf(Class elementType) {
+    public static > @Modifiable @IteratorPolyMod EnumSet allOf(Class elementType) {
         EnumSet result = noneOf(elementType);
         result.addAll();
         return result;
@@ -161,7 +161,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @return A copy of the specified enum set.
      * @throws NullPointerException if {@code s} is null
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet copyOf(EnumSet s) {
+    public static > @Modifiable @IteratorPolyMod EnumSet copyOf(EnumSet s) {
         return s.clone();
     }
 
@@ -179,7 +179,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      *     {@code EnumSet} instance and contains no elements
      * @throws NullPointerException if {@code c} is null
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet copyOf(Collection c) {
+    public static > @Modifiable @IteratorPolyMod EnumSet copyOf(Collection c) {
         if (c instanceof EnumSet) {
             return ((EnumSet)c).clone();
         } else {
@@ -204,7 +204,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @return The complement of the specified set in this set
      * @throws NullPointerException if {@code s} is null
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet complementOf(EnumSet s) {
+    public static > @Modifiable @IteratorPolyMod EnumSet complementOf(EnumSet s) {
         EnumSet result = copyOf(s);
         result.complement();
         return result;
@@ -224,7 +224,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @throws NullPointerException if {@code e} is null
      * @return an enum set initially containing the specified element
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet of(E e) {
+    public static > @Modifiable @IteratorPolyMod EnumSet of(E e) {
         EnumSet result = noneOf(e.getDeclaringClass());
         result.add(e);
         return result;
@@ -245,7 +245,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @throws NullPointerException if any parameters are null
      * @return an enum set initially containing the specified elements
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2) {
+    public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2) {
         EnumSet result = noneOf(e1.getDeclaringClass());
         result.add(e1);
         result.add(e2);
@@ -268,7 +268,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @throws NullPointerException if any parameters are null
      * @return an enum set initially containing the specified elements
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2, E e3) {
+    public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3) {
         EnumSet result = noneOf(e1.getDeclaringClass());
         result.add(e1);
         result.add(e2);
@@ -293,7 +293,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @throws NullPointerException if any parameters are null
      * @return an enum set initially containing the specified elements
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2, E e3, E e4) {
+    public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3, E e4) {
         EnumSet result = noneOf(e1.getDeclaringClass());
         result.add(e1);
         result.add(e2);
@@ -320,7 +320,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @throws NullPointerException if any parameters are null
      * @return an enum set initially containing the specified elements
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet of(E e1, E e2, E e3, E e4,
+    public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3, E e4,
                                                     E e5)
     {
         EnumSet result = noneOf(e1.getDeclaringClass());
@@ -347,7 +347,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @return an enum set initially containing the specified elements
      */
     @SafeVarargs
-    public static > @Modifiable @IteratorPolyShrink EnumSet of(E first, E... rest) {
+    public static > @Modifiable @IteratorPolyMod EnumSet of(E first, E... rest) {
         EnumSet result = noneOf(first.getDeclaringClass());
         result.add(first);
         for (E e : rest)
@@ -369,7 +369,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      * @return an enum set initially containing all of the elements in the
      *         range defined by the two specified endpoints
      */
-    public static > @Modifiable @IteratorPolyShrink EnumSet range(E from, E to) {
+    public static > @Modifiable @IteratorPolyMod EnumSet range(E from, E to) {
         if (from.compareTo(to) > 0)
             throw new IllegalArgumentException(from + " > " + to);
         EnumSet result = noneOf(from.getDeclaringClass());
@@ -391,7 +391,7 @@ public abstract sealed class EnumSet> extends AbstractSet
      */
     @SuppressWarnings("unchecked")
     @DoesNotUnrefineReceiver("modifiability")
-    public @Modifiable @IteratorPolyShrink EnumSet clone() {
+    public @Modifiable @IteratorPolyMod EnumSet clone() {
         try {
             return (EnumSet) super.clone();
         } catch(CloneNotSupportedException e) {
diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java
index 5844a7ac800b..f79d9248c75a 100644
--- a/src/java.base/share/classes/java/util/HashMap.java
+++ b/src/java.base/share/classes/java/util/HashMap.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -953,7 +953,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied
      * @return a set view of the keys contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) {
         Set ks = keySet;
         if (ks == null) {
@@ -1092,7 +1092,7 @@ public final void forEach(Consumer action) {
      * @return a view of the values contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) {
         Collection vs = values;
         if (vs == null) {
@@ -1159,7 +1159,7 @@ public final void forEach(Consumer action) {
      * @return a set view of the mappings contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) {
         Set> es;
         return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java
index 7be9d3d37a41..51241b4ee3a4 100644
--- a/src/java.base/share/classes/java/util/HashSet.java
+++ b/src/java.base/share/classes/java/util/HashSet.java
@@ -29,7 +29,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -126,7 +126,7 @@ public class HashSet
      * Constructs a new, empty set; the backing {@code HashMap} instance has
      * default initial capacity (16) and load factor (0.75).
      */
-    public @Modifiable @IteratorPolyShrink HashSet() {
+    public @Modifiable @IteratorPolyMod HashSet() {
         map = new HashMap<>();
     }
 
@@ -139,7 +139,7 @@ public class HashSet
      * @param c the collection whose elements are to be placed into this set
      * @throws NullPointerException if the specified collection is null
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) {
         map = HashMap.newHashMap(Math.max(c.size(), 12));
         addAll(c);
     }
@@ -157,7 +157,7 @@ public class HashSet
      * @throws     IllegalArgumentException if the initial capacity is less
      *             than zero, or if the load factor is nonpositive
      */
-    public @Modifiable @IteratorPolyShrink HashSet(@NonNegative int initialCapacity, float loadFactor) {
+    public @Modifiable @IteratorPolyMod HashSet(@NonNegative int initialCapacity, float loadFactor) {
         map = new HashMap<>(initialCapacity, loadFactor);
     }
 
@@ -173,7 +173,7 @@ public class HashSet
      * @throws     IllegalArgumentException if the initial capacity is less
      *             than zero
      */
-    public @Modifiable @IteratorPolyShrink HashSet(@NonNegative int initialCapacity) {
+    public @Modifiable @IteratorPolyMod HashSet(@NonNegative int initialCapacity) {
         map = new HashMap<>(initialCapacity);
     }
 
@@ -190,7 +190,7 @@ public class HashSet
      * @throws     IllegalArgumentException if the initial capacity is less
      *             than zero, or if the load factor is nonpositive
      */
-    @Modifiable @IteratorPolyShrink HashSet(int initialCapacity, float loadFactor, boolean dummy) {
+    @Modifiable @IteratorPolyMod HashSet(int initialCapacity, float loadFactor, boolean dummy) {
         map = new LinkedHashMap<>(initialCapacity, loadFactor);
     }
 
@@ -294,7 +294,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) {
      */
     @SideEffectFree
     @SuppressWarnings("unchecked")
-    public @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied HashSet this) {
+    public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied HashSet this) {
         try {
             HashSet newSet = (HashSet) super.clone();
             newSet.map = (HashMap) map.clone();
diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java
index 03538b97454b..8f7002309c6e 100644
--- a/src/java.base/share/classes/java/util/Hashtable.java
+++ b/src/java.base/share/classes/java/util/Hashtable.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -703,7 +703,7 @@ private  Iterator getIterator(int type) {
      * @since 1.2
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) {
         if (keySet == null)
             keySet = Collections.synchronizedSet(new KeySet(), this);
@@ -751,7 +751,7 @@ public void clear() {
      * @since 1.2
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) {
         if (entrySet==null)
             entrySet = Collections.synchronizedSet(new EntrySet(), this);
@@ -840,7 +840,7 @@ public void clear() {
      * @since 1.2
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) {
         if (values==null)
             values = Collections.synchronizedCollection(new ValueCollection(),
diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java
index d60fdf0a4b6c..d4cfc483288e 100644
--- a/src/java.base/share/classes/java/util/IdentityHashMap.java
+++ b/src/java.base/share/classes/java/util/IdentityHashMap.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -1035,7 +1035,7 @@ private void checkIndexForEntryUse() {
      * @see System#identityHashCode(Object)
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) {
         Set ks = keySet;
         if (ks == null) {
@@ -1152,7 +1152,7 @@ public Spliterator spliterator() {
      * {@code containsAll} methods.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) {
         Collection vs = values;
         if (vs == null) {
@@ -1269,7 +1269,7 @@ public Spliterator spliterator() {
      * @return a set view of the identity-mappings contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) {
         Set> es = entrySet;
         if (es != null)
diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java
index 5f9952db62aa..a20d9dcc73b0 100644
--- a/src/java.base/share/classes/java/util/LinkedHashMap.java
+++ b/src/java.base/share/classes/java/util/LinkedHashMap.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -655,7 +655,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma
      * @return a set view of the keys contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) {
         return sequencedKeySet();
     }
@@ -816,7 +816,7 @@ public SequencedSet reversed() {
      *
      * @return a view of the values contained in this map
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) {
         return sequencedValues();
     }
@@ -932,7 +932,7 @@ public SequencedCollection reversed() {
      * @return a set view of the mappings contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) {
         return sequencedEntrySet();
     }
@@ -1232,17 +1232,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) {
             base.clear();
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set keySet() {
             return base.sequencedKeySet().reversed();
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Collection values() {
             return base.sequencedValues().reversed();
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set> entrySet() {
             return base.sequencedEntrySet().reversed();
         }
diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java
index 725fdabd7880..c592552080f2 100644
--- a/src/java.base/share/classes/java/util/LinkedHashSet.java
+++ b/src/java.base/share/classes/java/util/LinkedHashSet.java
@@ -26,7 +26,7 @@
 package java.util;
 
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
 import org.checkerframework.checker.modifiability.qual.UnknownModifiability;
@@ -154,7 +154,7 @@ public class LinkedHashSet
      * @throws     IllegalArgumentException  if the initial capacity is less
      *               than zero, or if the load factor is nonpositive
      */
-    public @Modifiable @IteratorPolyShrink LinkedHashSet(int initialCapacity, float loadFactor) {
+    public @Modifiable @IteratorPolyMod LinkedHashSet(int initialCapacity, float loadFactor) {
         super(initialCapacity, loadFactor, true);
     }
 
@@ -170,7 +170,7 @@ public class LinkedHashSet
      * @throws  IllegalArgumentException if the initial capacity is less
      *              than zero
      */
-    public @Modifiable @IteratorPolyShrink LinkedHashSet(int initialCapacity) {
+    public @Modifiable @IteratorPolyMod LinkedHashSet(int initialCapacity) {
         super(initialCapacity, .75f, true);
     }
 
@@ -178,7 +178,7 @@ public class LinkedHashSet
      * Constructs a new, empty linked hash set with the default initial
      * capacity (16) and load factor (0.75).
      */
-    public @Modifiable @IteratorPolyShrink LinkedHashSet() {
+    public @Modifiable @IteratorPolyMod LinkedHashSet() {
         super(16, .75f, true);
     }
 
@@ -192,7 +192,7 @@ public class LinkedHashSet
      *           this set
      * @throws NullPointerException if the specified collection is null
      */
-    public @Modifiable @IteratorPolyShrink LinkedHashSet(Collection c) {
+    public @Modifiable @IteratorPolyMod LinkedHashSet(Collection c) {
         super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true);
         addAll(c);
     }
diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java
index 57fc993eec14..d2ecaa17bb68 100644
--- a/src/java.base/share/classes/java/util/LinkedList.java
+++ b/src/java.base/share/classes/java/util/LinkedList.java
@@ -32,7 +32,7 @@
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.lock.qual.ReleasesNoLocks;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Replaceable;
@@ -144,7 +144,7 @@ void dataStructureInvariants() {
     /**
      * Constructs an empty list.
      */
-    public @Modifiable @IteratorPolyShrink LinkedList() {
+    public @Modifiable @IteratorPolyMod LinkedList() {
     }
 
     /**
@@ -155,7 +155,7 @@ void dataStructureInvariants() {
      * @param  c the collection whose elements are to be placed into this list
      * @throws NullPointerException if the specified collection is null
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) {
         this();
         addAll(c);
     }
@@ -1113,7 +1113,7 @@ private LinkedList superClone() {
      * @return a shallow copy of this {@code LinkedList} instance
      */
     @SideEffectFree
-    public @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied LinkedList this) {
+    public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied LinkedList this) {
         LinkedList clone = superClone();
 
         // Put clone into "virgin" state
diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java
index 0c2f1f039d3c..3f421077e00c 100644
--- a/src/java.base/share/classes/java/util/Map.java
+++ b/src/java.base/share/classes/java/util/Map.java
@@ -29,7 +29,7 @@
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.lock.qual.ReleasesNoLocks;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -404,7 +404,7 @@ public interface Map {
      * @return a set view of the keys contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this);
 
     /**
@@ -423,7 +423,7 @@ public interface Map {
      * @return a collection view of the values contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this);
 
     /**
@@ -443,7 +443,7 @@ public interface Map {
      * @return a set view of the mappings contained in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this);
 
     /**
diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java
index b5bbcf9c16a9..f6e1bf285579 100644
--- a/src/java.base/share/classes/java/util/NavigableMap.java
+++ b/src/java.base/share/classes/java/util/NavigableMap.java
@@ -36,7 +36,7 @@
 package java.util;
 
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -313,7 +313,7 @@ public interface NavigableMap extends SortedMap {
      * @return a navigable set view of the keys in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this);
 
     /**
@@ -331,7 +331,7 @@ public interface NavigableMap extends SortedMap {
      * @return a reverse order navigable set view of the keys in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this);
 
     /**
diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java
index 71957f343a2c..3ba09c372fd1 100644
--- a/src/java.base/share/classes/java/util/PriorityQueue.java
+++ b/src/java.base/share/classes/java/util/PriorityQueue.java
@@ -31,7 +31,7 @@
 import org.checkerframework.checker.index.qual.Positive;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -152,7 +152,7 @@ public class PriorityQueue extends AbstractQueue
      * capacity (11) that orders its elements according to their
      * {@linkplain Comparable natural ordering}.
      */
-    public @Modifiable @IteratorPolyShrink PriorityQueue() {
+    public @Modifiable @IteratorPolyMod PriorityQueue() {
         this(DEFAULT_INITIAL_CAPACITY, null);
     }
 
@@ -165,7 +165,7 @@ public class PriorityQueue extends AbstractQueue
      * @throws IllegalArgumentException if {@code initialCapacity} is less
      *         than 1
      */
-    public @Modifiable @IteratorPolyShrink PriorityQueue(@Positive int initialCapacity) {
+    public @Modifiable @IteratorPolyMod PriorityQueue(@Positive int initialCapacity) {
         this(initialCapacity, null);
     }
 
@@ -178,7 +178,7 @@ public class PriorityQueue extends AbstractQueue
      *         natural ordering} of the elements will be used.
      * @since 1.8
      */
-    public @Modifiable @IteratorPolyShrink PriorityQueue(Comparator comparator) {
+    public @Modifiable @IteratorPolyMod PriorityQueue(Comparator comparator) {
         this(DEFAULT_INITIAL_CAPACITY, comparator);
     }
 
@@ -193,7 +193,7 @@ public class PriorityQueue extends AbstractQueue
      * @throws IllegalArgumentException if {@code initialCapacity} is
      *         less than 1
      */
-    public @Modifiable @IteratorPolyShrink PriorityQueue(@Positive int initialCapacity,
+    public @Modifiable @IteratorPolyMod PriorityQueue(@Positive int initialCapacity,
                          Comparator comparator) {
         // Note: This restriction of at least one is not actually needed,
         // but continues for 1.5 compatibility
@@ -219,7 +219,7 @@ public class PriorityQueue extends AbstractQueue
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) {
         if (c instanceof SortedSet) {
             SortedSet ss = (SortedSet) c;
             this.comparator = (Comparator) ss.comparator();
@@ -250,7 +250,7 @@ else if (c instanceof PriorityQueue) {
      * @throws NullPointerException if the specified priority queue or any
      *         of its elements are null
      */
-    public @Modifiable @IteratorPolyShrink PriorityQueue(PriorityQueue c) {
+    public @Modifiable @IteratorPolyMod PriorityQueue(PriorityQueue c) {
         this.comparator = (Comparator) c.comparator();
         initFromPriorityQueue(c);
     }
@@ -268,7 +268,7 @@ else if (c instanceof PriorityQueue) {
      * @throws NullPointerException if the specified sorted set or any
      *         of its elements are null
      */
-    public @Modifiable @IteratorPolyShrink PriorityQueue(SortedSet c) {
+    public @Modifiable @IteratorPolyMod PriorityQueue(SortedSet c) {
         this.comparator = (Comparator) c.comparator();
         initElementsFromCollection(c);
     }
diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java
index c43ca8edbd40..ddfde6957f6e 100644
--- a/src/java.base/share/classes/java/util/Properties.java
+++ b/src/java.base/share/classes/java/util/Properties.java
@@ -26,7 +26,7 @@
 package java.util;
 
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf;
 import org.checkerframework.checker.nullness.qual.KeyFor;
 import org.checkerframework.checker.nullness.qual.Nullable;
@@ -1395,20 +1395,20 @@ public synchronized String toString() {
     }
 
     @Override
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public Set<@KeyFor("this") Object> keySet() {
         return Collections.synchronizedSet(map.keySet(), this);
     }
 
     @Override
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public Collection values() {
         return Collections.synchronizedCollection(map.values(), this);
     }
 
     @Override
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public Set> entrySet() {
         return Collections.synchronizedSet(new EntrySet(map.entrySet()), this);
     }
diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java
index 504a43e984a8..65d942e22c4a 100644
--- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java
+++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java
@@ -25,7 +25,7 @@
 
 package java.util;
 
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.dataflow.qual.Pure;
 
 /**
@@ -98,7 +98,7 @@ public int size() {
         return base.size();
     }
 
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public Set keySet() {
         return new AbstractSet<>() {
             // inherit add(), which throws UOE
@@ -110,7 +110,7 @@ public Set keySet() {
         };
     }
 
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public Collection values() {
         return new AbstractCollection<>() {
             // inherit add(), which throws UOE
@@ -122,7 +122,7 @@ public Collection values() {
         };
     }
 
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public Set> entrySet() {
         return new AbstractSet<>() {
             // inherit add(), which throws UOE
@@ -398,7 +398,7 @@ public String toString() {
             return ReverseOrderSortedMapView.toString(this, entryIterator());
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set> entrySet() {
             return new AbstractSet<>() {
                 public Iterator> iterator() {
diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java
index 1b3bba1cdbd5..4fe4488df1da 100644
--- a/src/java.base/share/classes/java/util/SortedMap.java
+++ b/src/java.base/share/classes/java/util/SortedMap.java
@@ -26,7 +26,7 @@
 package java.util;
 
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -265,7 +265,7 @@ public interface SortedMap extends SequencedMap {
      *         ascending order
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this);
 
     /**
@@ -287,7 +287,7 @@ public interface SortedMap extends SequencedMap {
      *         sorted in ascending key order
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this);
 
     /**
@@ -309,7 +309,7 @@ public interface SortedMap extends SequencedMap {
      *         sorted in ascending key order
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this);
 
     /**
diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java
index 02db44159d67..b82161d87056 100644
--- a/src/java.base/share/classes/java/util/Stack.java
+++ b/src/java.base/share/classes/java/util/Stack.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.CanShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
 import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf;
@@ -67,7 +67,7 @@ public class Stack extends Vector {
     /**
      * Creates an empty Stack.
      */
-    public @Modifiable @IteratorPolyShrink Stack() {
+    public @Modifiable @IteratorPolyMod Stack() {
     }
 
     /**
diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java
index 07690bc38ed1..ce4f853be24a 100644
--- a/src/java.base/share/classes/java/util/TreeMap.java
+++ b/src/java.base/share/classes/java/util/TreeMap.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -1190,7 +1190,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) {
      * operations.
      */
     @DoesNotUnrefineReceiver("modifiability")
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) {
         return navigableKeySet();
     }
@@ -1199,7 +1199,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) {
      * @since 1.6
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) {
         KeySet nks = navigableKeySet;
         return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this));
@@ -1209,7 +1209,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) {
      * @since 1.6
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) {
         return descendingMap().navigableKeySet();
     }
@@ -1235,7 +1235,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) {
      * {@code retainAll} and {@code clear} operations.  It does not
      * support the {@code add} or {@code addAll} operations.
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) {
         Collection vs = values;
         if (vs == null) {
@@ -1268,7 +1268,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) {
      * {@code add} or {@code addAll} operations.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) {
         EntrySet es = entrySet;
         return (es != null) ? es : (entrySet = new EntrySet());
@@ -2059,20 +2059,20 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this)
         transient KeySet navigableKeySetView;
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public final NavigableSet navigableKeySet() {
             KeySet nksv = navigableKeySetView;
             return (nksv != null) ? nksv :
                 (navigableKeySetView = new TreeMap.KeySet<>(this));
         }
 
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public final Set keySet() {
             return navigableKeySet();
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public NavigableSet descendingKeySet() {
             return descendingMap().navigableKeySet();
         }
@@ -2399,7 +2399,7 @@ public Iterator> iterator() {
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set> entrySet() {
             EntrySetView es = entrySetView;
             return (es != null) ? es : (entrySetView = new AscendingEntrySetView());
@@ -2493,7 +2493,7 @@ public Iterator> iterator() {
         }
 
         @SideEffectFree
-        @IteratorPolyShrink
+        @IteratorPolyMod
         public Set> entrySet() {
             EntrySetView es = entrySetView;
             return (es != null) ? es : (entrySetView = new DescendingEntrySetView());
diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java
index ef75d358475c..786be122f4c3 100644
--- a/src/java.base/share/classes/java/util/TreeSet.java
+++ b/src/java.base/share/classes/java/util/TreeSet.java
@@ -29,7 +29,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -131,7 +131,7 @@ public class TreeSet extends AbstractSet
     /**
      * Constructs a set backed by the specified navigable map.
      */
-    @Modifiable @IteratorPolyShrink TreeSet(NavigableMap m) {
+    @Modifiable @IteratorPolyMod TreeSet(NavigableMap m) {
         this.m = m;
     }
 
@@ -148,7 +148,7 @@ public class TreeSet extends AbstractSet
      * integers), the {@code add} call will throw a
      * {@code ClassCastException}.
      */
-    public @Modifiable @IteratorPolyShrink TreeSet() {
+    public @Modifiable @IteratorPolyMod TreeSet() {
         this(new TreeMap<>());
     }
 
@@ -165,7 +165,7 @@ public class TreeSet extends AbstractSet
      *        If {@code null}, the {@linkplain Comparable natural
      *        ordering} of the elements will be used.
      */
-    public @Modifiable @IteratorPolyShrink TreeSet(@Nullable Comparator comparator) {
+    public @Modifiable @IteratorPolyMod TreeSet(@Nullable Comparator comparator) {
         this(new TreeMap<>(comparator));
     }
 
@@ -183,7 +183,7 @@ public class TreeSet extends AbstractSet
      *         not {@link Comparable}, or are not mutually comparable
      * @throws NullPointerException if the specified collection is null
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) {
         this();
         addAll(c);
     }
@@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet
      * @param s sorted set whose elements will comprise the new set
      * @throws NullPointerException if the specified sorted set is null
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) {
         this(s.comparator());
         addAll(s);
     }
@@ -553,7 +553,7 @@ public void addLast(E e) {
      */
     @SideEffectFree
     @SuppressWarnings("unchecked")
-    public @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied TreeSet this) {
+    public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied TreeSet this) {
         TreeSet clone;
         try {
             clone = (TreeSet) super.clone();
diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java
index 3c1b26f31194..54bf76f120e3 100644
--- a/src/java.base/share/classes/java/util/Vector.java
+++ b/src/java.base/share/classes/java/util/Vector.java
@@ -31,7 +31,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Replaceable;
@@ -167,7 +167,7 @@ public class Vector
      * @throws IllegalArgumentException if the specified initial capacity
      *         is negative
      */
-    public @Modifiable @IteratorPolyShrink Vector(@NonNegative int initialCapacity, int capacityIncrement) {
+    public @Modifiable @IteratorPolyMod Vector(@NonNegative int initialCapacity, int capacityIncrement) {
         super();
         if (initialCapacity < 0)
             throw new IllegalArgumentException("Illegal Capacity: "+
@@ -184,7 +184,7 @@ public class Vector
      * @throws IllegalArgumentException if the specified initial capacity
      *         is negative
      */
-    public @Modifiable @IteratorPolyShrink Vector(@NonNegative int initialCapacity) {
+    public @Modifiable @IteratorPolyMod Vector(@NonNegative int initialCapacity) {
         this(initialCapacity, 0);
     }
 
@@ -193,7 +193,7 @@ public class Vector
      * has size {@code 10} and its standard capacity increment is
      * zero.
      */
-    public @Modifiable @IteratorPolyShrink Vector() {
+    public @Modifiable @IteratorPolyMod Vector() {
         this(10);
     }
 
@@ -207,7 +207,7 @@ public class Vector
      * @throws NullPointerException if the specified collection is null
      * @since   1.2
      */
-    public @Modifiable @IteratorPolyShrink @PolyNonEmpty Vector(@PolyNonEmpty Collection c) {
+    public @Modifiable @IteratorPolyMod @PolyNonEmpty Vector(@PolyNonEmpty Collection c) {
         Object[] a = c.toArray();
         elementCount = a.length;
         if (c.getClass() == ArrayList.class) {
@@ -712,7 +712,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin
      * @return  a clone of this vector
      */
     @SideEffectFree
-    public synchronized @Modifiable @IteratorPolyShrink Object clone(@GuardSatisfied Vector this) {
+    public synchronized @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied Vector this) {
         try {
             @SuppressWarnings("unchecked")
             Vector v = (Vector) super.clone();
diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java
index 71da4ded8434..1beb700246f4 100644
--- a/src/java.base/share/classes/java/util/WeakHashMap.java
+++ b/src/java.base/share/classes/java/util/WeakHashMap.java
@@ -28,7 +28,7 @@
 import org.checkerframework.checker.index.qual.NonNegative;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -922,7 +922,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) {
      * operations.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) {
         Set ks = keySet;
         if (ks == null) {
@@ -984,7 +984,7 @@ public Spliterator spliterator() {
      * support the {@code add} or {@code addAll} operations.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) {
         Collection vs = values;
         if (vs == null) {
@@ -1037,7 +1037,7 @@ public Spliterator spliterator() {
      * {@code add} or {@code addAll} operations.
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) {
         Set> es = entrySet;
         return es != null ? es : (entrySet = new EntrySet());
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 8b3ec37eb656..7452cfe05578 100644
--- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java
+++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java
@@ -39,7 +39,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -276,7 +276,7 @@ void removeAt(final int removeIndex) {
      * @param capacity the capacity of this queue
      * @throws IllegalArgumentException if {@code capacity < 1}
      */
-    public @Modifiable @IteratorPolyShrink ArrayBlockingQueue(int capacity) {
+    public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity) {
         this(capacity, false);
     }
 
@@ -290,7 +290,7 @@ void removeAt(final int removeIndex) {
      *        if {@code false} the access order is unspecified.
      * @throws IllegalArgumentException if {@code capacity < 1}
      */
-    public @Modifiable @IteratorPolyShrink ArrayBlockingQueue(int capacity, boolean fair) {
+    public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity, boolean fair) {
         if (capacity <= 0)
             throw new IllegalArgumentException();
         this.items = new Object[capacity];
@@ -315,7 +315,7 @@ void removeAt(final int removeIndex) {
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
-    public @Modifiable @IteratorPolyShrink ArrayBlockingQueue(int capacity, boolean fair,
+    public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity, boolean fair,
                               Collection c) {
         this(capacity, fair);
 
diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java
index 7616cc460089..14090d402e50 100644
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java
@@ -37,7 +37,7 @@
 
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -1280,7 +1280,7 @@ else if ((fh = f.hash) == MOVED) {
      * @return the set view
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public KeySetView<@KeyFor({"this"}) K,V> keySet() {
         KeySetView ks;
         if ((ks = keySet) != null) return ks;
@@ -1306,7 +1306,7 @@ else if ((fh = f.hash) == MOVED) {
      * @return the collection view
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) {
         ValuesView vs;
         if ((vs = values) != null) return vs;
@@ -1331,7 +1331,7 @@ else if ((fh = f.hash) == MOVED) {
      * @return the set view
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) {
         EntrySetView es;
         if ((es = entrySet) != null) return es;
@@ -2287,7 +2287,7 @@ public static  KeySetView newKeySet(int initialCapacity) {
      * @return the set view
      * @throws NullPointerException if the mappedValue is null
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public KeySetView keySet(V mappedValue) {
         if (mappedValue == null)
             throw new NullPointerException();
diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java
index f7c3ccf7e476..a3427f395589 100644
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java
@@ -39,7 +39,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -793,7 +793,7 @@ private E screenNullResult(@NonNull E v) {
     /**
      * Constructs an empty deque.
      */
-    public @Modifiable @IteratorPolyShrink ConcurrentLinkedDeque() {
+    public @Modifiable @IteratorPolyMod ConcurrentLinkedDeque() {
         head = tail = new Node();
     }
 
@@ -806,7 +806,7 @@ private E screenNullResult(@NonNull E v) {
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
-    public @Modifiable @IteratorPolyShrink ConcurrentLinkedDeque(Collection c) {
+    public @Modifiable @IteratorPolyMod ConcurrentLinkedDeque(Collection c) {
         // Copy c into a private chain of Nodes
         Node h = null, t = null;
         for (E e : c) {
diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java
index a424fe252d47..3502f7e5c323 100644
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java
@@ -39,7 +39,7 @@
 import org.checkerframework.checker.index.qual.PolyGrowShrink;
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.Shrinkable;
@@ -265,7 +265,7 @@ boolean casItem(E cmp, E val) {
     /**
      * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
      */
-    public @Modifiable @IteratorPolyShrink ConcurrentLinkedQueue() {
+    public @Modifiable @IteratorPolyMod ConcurrentLinkedQueue() {
         head = tail = new Node();
     }
 
@@ -278,7 +278,7 @@ boolean casItem(E cmp, E val) {
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
-    public @Modifiable @IteratorPolyShrink ConcurrentLinkedQueue(Collection c) {
+    public @Modifiable @IteratorPolyMod ConcurrentLinkedQueue(Collection c) {
         Node h = null, t = null;
         for (E e : c) {
             Node newNode = new Node(Objects.requireNonNull(e));
diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java
index c4cb851d62b7..e59ef4ae1279 100644
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java
@@ -36,7 +36,7 @@
 package java.util.concurrent;
 
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
 import org.checkerframework.checker.modifiability.qual.Ungrowable;
 import org.checkerframework.dataflow.qual.SideEffectFree;
@@ -147,7 +147,7 @@ public interface ConcurrentNavigableMap
      * @return a navigable set view of the keys in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this);
 
     /**
@@ -168,7 +168,7 @@ public interface ConcurrentNavigableMap
      *
      * @return a navigable set view of the keys in this map
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this);
 
     /**
@@ -188,6 +188,6 @@ public interface ConcurrentNavigableMap
      * @return a reverse order navigable set view of the keys in this map
      */
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this);
 }
diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java
index 0058e4e7a7e4..467901acf536 100644
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java
@@ -37,7 +37,7 @@
 
 import org.checkerframework.checker.lock.qual.GuardSatisfied;
 import org.checkerframework.checker.modifiability.qual.Growable;
-import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink;
+import org.checkerframework.checker.modifiability.qual.IteratorPolyMod;
 import org.checkerframework.checker.modifiability.qual.Modifiable;
 import org.checkerframework.checker.modifiability.qual.PolyModifiable;
 import org.checkerframework.checker.modifiability.qual.PolyShrink;
@@ -1650,7 +1650,7 @@ else if (doRemove(key, v) != null)
      *
      * @return a navigable set view of the keys in this map
      */
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) {
         KeySet ks;
         if ((ks = keySet) != null) return ks;
@@ -1658,7 +1658,7 @@ else if (doRemove(key, v) != null)
     }
 
     @SideEffectFree
-    @IteratorPolyShrink
+    @IteratorPolyMod
     public @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) {
         KeySet ks;
         if ((ks = keySet) != null) return ks;
@@ -1684,7 +1684,7 @@ else if (doRemove(key, v) != null)
      * 

The view's iterators and spliterators are * weakly consistent. */ - @IteratorPolyShrink + @IteratorPolyMod public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; @@ -1719,7 +1719,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - @IteratorPolyShrink + @IteratorPolyMod public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; @@ -1735,7 +1735,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - @IteratorPolyShrink + @IteratorPolyMod public @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3016,7 +3016,7 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ - @IteratorPolyShrink + @IteratorPolyMod public NavigableSet keySet() { KeySet ks; if ((ks = keySetView) != null) return ks; @@ -3024,14 +3024,14 @@ public NavigableSet keySet() { } @SideEffectFree - @IteratorPolyShrink + @IteratorPolyMod public NavigableSet navigableKeySet() { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } - @IteratorPolyShrink + @IteratorPolyMod public Collection values() { Values vs; if ((vs = valuesView) != null) return vs; @@ -3039,7 +3039,7 @@ public Collection values() { } @SideEffectFree - @IteratorPolyShrink + @IteratorPolyMod public Set> entrySet() { EntrySet es; if ((es = entrySetView) != null) return es; @@ -3047,7 +3047,7 @@ public Set> entrySet() { } @SideEffectFree - @IteratorPolyShrink + @IteratorPolyMod public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 0fb0ff395c85..6655663deaa3 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -132,7 +132,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet() { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -144,7 +144,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -159,7 +159,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(Collection c) { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -172,7 +172,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(SortedSet s) { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -180,7 +180,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable @IteratorPolyShrink ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable @IteratorPolyMod ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -191,7 +191,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable @IteratorPolyShrink ConcurrentSkipListSet clone() { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index b91d904b7fc1..5ff56d96dd5b 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -154,7 +154,7 @@ public class DelayQueue extends AbstractQueue /** * Creates a new {@code DelayQueue} that is initially empty. */ - public @Modifiable @IteratorPolyShrink DelayQueue() {} + public @Modifiable @IteratorPolyMod DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -164,7 +164,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink DelayQueue(Collection c) { + public @Modifiable @IteratorPolyMod DelayQueue(Collection c) { this.addAll(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 c1c73012e080..0b3a77f0bdad 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -194,7 +194,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPolyShrink LinkedBlockingDeque() { + public @Modifiable @IteratorPolyMod LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -204,7 +204,7 @@ static final class Node { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public @Modifiable @IteratorPolyShrink LinkedBlockingDeque(int capacity) { + public @Modifiable @IteratorPolyMod LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -219,7 +219,7 @@ static final class Node { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink LinkedBlockingDeque(Collection c) { + public @Modifiable @IteratorPolyMod LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } 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 4983400e1ab9..da6e97349f06 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -264,7 +264,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPolyShrink LinkedBlockingQueue() { + public @Modifiable @IteratorPolyMod LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -275,7 +275,7 @@ void fullyUnlock() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public @Modifiable @IteratorPolyShrink LinkedBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyMod LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -291,7 +291,7 @@ void fullyUnlock() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink LinkedBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyMod LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index fa885e110bec..d034769b8315 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1179,7 +1179,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public @Modifiable @IteratorPolyShrink LinkedTransferQueue() { + public @Modifiable @IteratorPolyMod LinkedTransferQueue() { head = tail = new Node(); } @@ -1192,7 +1192,7 @@ else if (s == n) // stale * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink LinkedTransferQueue(Collection c) { + public @Modifiable @IteratorPolyMod LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(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 9cdf7500b254..dec4dfc3b25d 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrink; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -210,7 +210,7 @@ public class PriorityBlockingQueue extends AbstractQueue * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyShrink PriorityBlockingQueue() { + public @Modifiable @IteratorPolyMod PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -223,7 +223,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyShrink PriorityBlockingQueue(int initialCapacity) { + public @Modifiable @IteratorPolyMod PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -239,7 +239,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyShrink PriorityBlockingQueue(int initialCapacity, + public @Modifiable @IteratorPolyMod PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -263,7 +263,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrink PriorityBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyMod PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { From 475bc857e19dfbcdc7e86c30394d220c7412abca Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 3 May 2026 21:21:53 -0700 Subject: [PATCH 070/119] rename IteratorPolyShrink with IteratorPolyMod --- .../{IteratorPolyShrink.java => IteratorPolyMod.java} | 8 ++++---- ...teratorPolyShrink.java => UnknownIteratorPolyMod.java} | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{IteratorPolyShrink.java => IteratorPolyMod.java} (73%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnknownIteratorPolyShrink.java => UnknownIteratorPolyMod.java} (91%) diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java similarity index 73% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java index 164a8f8d1308..32f327fb02a0 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java @@ -8,10 +8,10 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * If a collection's type is {@code @IteratorPolyShrink}, then its {@code iterator()} method + * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} method * preserves the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has * type {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any - * collection whose type is {@code @UnknownIteratorPolyShrink}, its iterator is always + * collection whose type is {@code @UnknownIteratorPolyMod}, its iterator is always * {@code @Unshrinkable}. * * @checker_framework.manual #modifiability-checker Modifiability Checker @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownIteratorPolyShrink.class) -public @interface IteratorPolyShrink {} +@SubtypeOf(UnknownIteratorPolyMod.class) +public @interface IteratorPolyMod {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java similarity index 91% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java index b74f7b26c438..23746c289a4a 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java @@ -13,7 +13,7 @@ * *

This is the default qualifier for unannotated types. * - * @see #IteratorPolyShrink + * @see #IteratorPolyMod * @checker_framework.manual #modifiability-checker Modifiability Checker */ @Documented @@ -21,4 +21,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface UnknownIteratorPolyShrink {} +public @interface UnknownIteratorPolyMod {} From b11a5ee615e15bd4528db91505719d43d270dcff Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 7 May 2026 14:31:10 -0700 Subject: [PATCH 071/119] fixed the location of @iteratorPolyMod in map.java --- .../share/classes/java/util/AbstractMap.java | 9 ++--- .../share/classes/java/util/Collections.java | 36 +++++++------------ .../share/classes/java/util/EnumMap.java | 9 ++--- .../share/classes/java/util/HashMap.java | 9 ++--- .../share/classes/java/util/Hashtable.java | 9 ++--- .../classes/java/util/IdentityHashMap.java | 9 ++--- .../classes/java/util/LinkedHashMap.java | 18 ++++------ .../share/classes/java/util/Map.java | 9 ++--- .../share/classes/java/util/NavigableMap.java | 6 ++-- .../share/classes/java/util/Properties.java | 9 ++--- .../java/util/ReverseOrderSortedMapView.java | 12 +++---- .../share/classes/java/util/SortedMap.java | 9 ++--- .../share/classes/java/util/TreeMap.java | 30 ++++++---------- .../share/classes/java/util/WeakHashMap.java | 9 ++--- .../util/concurrent/ConcurrentHashMap.java | 12 +++---- .../concurrent/ConcurrentNavigableMap.java | 9 ++--- .../concurrent/ConcurrentSkipListMap.java | 30 ++++++---------- 17 files changed, 78 insertions(+), 156 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index b86bd2ff614f..7600b786e4b2 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -391,8 +391,7 @@ public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { * method will not all return the same set. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { @@ -462,8 +461,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { @@ -516,8 +514,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - @IteratorPolyMod - public abstract @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); + public abstract @IteratorPolyMod @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 17e1efdd82c0..1702a0129ac9 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -3087,8 +3087,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - @IteratorPolyMod - public Set keySet() { + public @IteratorPolyMod Set keySet() { synchronized (mutex) { if (keySet==null) keySet = new SynchronizedSet<>(m.keySet(), mutex); @@ -3097,8 +3096,7 @@ public Set keySet() { } @SideEffectFree - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { synchronized (mutex) { if (entrySet==null) entrySet = new SynchronizedSet<>(m.entrySet(), mutex); @@ -3106,8 +3104,7 @@ public Set> entrySet() { } } - @IteratorPolyMod - public Collection values() { + public @IteratorPolyMod Collection values() { synchronized (mutex) { if (values==null) values = new SynchronizedCollection<>(m.values(), mutex); @@ -3397,22 +3394,19 @@ public NavigableMap descendingMap() { } } - @IteratorPolyMod - public NavigableSet keySet() { + public @IteratorPolyMod NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPolyMod - public NavigableSet navigableKeySet() { + public @IteratorPolyMod NavigableSet navigableKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } @SideEffectFree - @IteratorPolyMod - public NavigableSet descendingKeySet() { + public @IteratorPolyMod NavigableSet descendingKeySet() { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } @@ -4191,10 +4185,8 @@ private String badValueMsg(Object value) { public V get(Object key) { return m.get(key); } public V remove(Object key) { return m.remove(key); } public void clear() { m.clear(); } - @IteratorPolyMod - public Set keySet() { return m.keySet(); } - @IteratorPolyMod - public Collection values() { return m.values(); } + public @IteratorPolyMod Set keySet() { return m.keySet(); } + public @IteratorPolyMod Collection values() { return m.values(); } public boolean equals(Object o) { return o == this || m.equals(o); } public int hashCode() { return m.hashCode(); } public String toString() { return m.toString(); } @@ -4229,8 +4221,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); return entrySet; @@ -4722,20 +4713,17 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - @IteratorPolyMod - public NavigableSet keySet() { + public @IteratorPolyMod NavigableSet keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPolyMod - public NavigableSet navigableKeySet() { + public @IteratorPolyMod NavigableSet navigableKeySet() { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - @IteratorPolyMod - public NavigableSet descendingKeySet() { + public @IteratorPolyMod NavigableSet descendingKeySet() { return checkedNavigableSet(nm.descendingKeySet(), keyType); } diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 9e6f081bdd5e..d8d83cf0c035 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -413,8 +413,7 @@ public void clear(@Shrinkable EnumMap this) { * * @return a set view of the keys contained in this enum map */ - @IteratorPolyMod - public @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -457,8 +456,7 @@ public void clear(@Shrinkable KeySet this) { * * @return a collection view of the values contained in this map */ - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -508,8 +506,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index f79d9248c75a..7bbb0fa8ead3 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -953,8 +953,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1092,8 +1091,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1159,8 +1157,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 8f7002309c6e..f9ed6296137b 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -703,8 +703,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); return keySet; @@ -751,8 +750,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); return entrySet; @@ -840,8 +838,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), this); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index d4cfc483288e..f696043ef1d1 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -1035,8 +1035,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1152,8 +1151,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1269,8 +1267,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index a20d9dcc73b0..c29665112620 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -655,8 +655,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { return sequencedKeySet(); } @@ -816,8 +815,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { return sequencedValues(); } @@ -932,8 +930,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -1232,18 +1229,15 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } - @IteratorPolyMod - public Set keySet() { + public @IteratorPolyMod Set keySet() { return base.sequencedKeySet().reversed(); } - @IteratorPolyMod - public Collection values() { + public @IteratorPolyMod Collection values() { return base.sequencedValues().reversed(); } - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 3f421077e00c..bbea6545fa71 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -404,8 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -423,8 +422,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -443,8 +441,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index f6e1bf285579..374870daaa8e 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -313,8 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); + @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -331,8 +330,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); + @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); /** * Returns a view of the portion of this map whose keys range from diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index ddfde6957f6e..3e09b33cc6f3 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -1395,21 +1395,18 @@ public synchronized String toString() { } @Override - @IteratorPolyMod - public Set<@KeyFor("this") Object> keySet() { + public @IteratorPolyMod Set<@KeyFor("this") Object> keySet() { return Collections.synchronizedSet(map.keySet(), this); } @Override - @IteratorPolyMod - public Collection values() { + public @IteratorPolyMod Collection values() { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 65d942e22c4a..8218273b4b1b 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -98,8 +98,7 @@ public int size() { return base.size(); } - @IteratorPolyMod - public Set keySet() { + public @IteratorPolyMod Set keySet() { return new AbstractSet<>() { // inherit add(), which throws UOE public Iterator iterator() { return descendingKeyIterator(base); } @@ -110,8 +109,7 @@ public Set keySet() { }; } - @IteratorPolyMod - public Collection values() { + public @IteratorPolyMod Collection values() { return new AbstractCollection<>() { // inherit add(), which throws UOE public Iterator iterator() { return descendingValueIterator(base); } @@ -122,8 +120,7 @@ public Collection values() { }; } - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { return new AbstractSet<>() { // inherit add(), which throws UOE public Iterator> iterator() { return descendingEntryIterator(base); } @@ -398,8 +395,7 @@ public String toString() { return ReverseOrderSortedMapView.toString(this, entryIterator()); } - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { return new AbstractSet<>() { public Iterator> iterator() { return entryIterator(); diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 4fe4488df1da..72372e592bd7 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -265,8 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -287,8 +286,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -309,8 +307,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** * Throws {@code UnsupportedOperationException}. The encounter order induced by this diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index ce4f853be24a..4e9d79f22bc6 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -1190,8 +1190,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @DoesNotUnrefineReceiver("modifiability") - @IteratorPolyMod - public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1199,8 +1198,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } @@ -1209,8 +1207,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1235,8 +1232,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1268,8 +1264,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } @@ -2059,21 +2054,18 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - @IteratorPolyMod - public final NavigableSet navigableKeySet() { + public final @IteratorPolyMod NavigableSet navigableKeySet() { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } - @IteratorPolyMod - public final Set keySet() { + public final @IteratorPolyMod Set keySet() { return navigableKeySet(); } @SideEffectFree - @IteratorPolyMod - public NavigableSet descendingKeySet() { + public @IteratorPolyMod NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } @@ -2399,8 +2391,7 @@ public Iterator> iterator() { } @SideEffectFree - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); } @@ -2493,8 +2484,7 @@ public Iterator> iterator() { } @SideEffectFree - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); } diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 1beb700246f4..a0665a32b9f2 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -922,8 +922,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -984,8 +983,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1037,8 +1035,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 14090d402e50..0b0741a93d8d 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -1280,8 +1280,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - @IteratorPolyMod - public KeySetView<@KeyFor({"this"}) K,V> keySet() { + public @IteratorPolyMod KeySetView<@KeyFor({"this"}) K,V> keySet() { KeySetView ks; if ((ks = keySet) != null) return ks; return keySet = new KeySetView(this, null); @@ -1306,8 +1305,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; return values = new ValuesView(this); @@ -1331,8 +1329,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); @@ -2287,8 +2284,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @return the set view * @throws NullPointerException if the mappedValue is null */ - @IteratorPolyMod - public KeySetView keySet(V mappedValue) { + public @IteratorPolyMod KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); return new KeySetView(this, mappedValue); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index e59ef4ae1279..00b522e13dea 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -147,8 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -168,8 +167,7 @@ public interface ConcurrentNavigableMap * * @return a navigable set view of the keys in this map */ - @IteratorPolyMod - @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -188,6 +186,5 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod - @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 467901acf536..9788b066fb51 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -1650,16 +1650,14 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ - @IteratorPolyMod - public @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); } @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); @@ -1684,8 +1682,7 @@ else if (doRemove(key, v) != null) *

The view's iterators and spliterators are * weakly consistent. */ - @IteratorPolyMod - public @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; return values = new Values<>(this); @@ -1719,8 +1716,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1735,8 +1731,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - @IteratorPolyMod - public @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3016,39 +3011,34 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ - @IteratorPolyMod - public NavigableSet keySet() { + public @IteratorPolyMod NavigableSet keySet() { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - @IteratorPolyMod - public NavigableSet navigableKeySet() { + public @IteratorPolyMod NavigableSet navigableKeySet() { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } - @IteratorPolyMod - public Collection values() { + public @IteratorPolyMod Collection values() { Values vs; if ((vs = valuesView) != null) return vs; return valuesView = new Values<>(this); } @SideEffectFree - @IteratorPolyMod - public Set> entrySet() { + public @IteratorPolyMod Set> entrySet() { EntrySet es; if ((es = entrySetView) != null) return es; return entrySetView = new EntrySet(this); } @SideEffectFree - @IteratorPolyMod - public NavigableSet descendingKeySet() { + public @IteratorPolyMod NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } From 1cdc8a51f4f8f88cea27a5f8c13e1015b6c6920a Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 7 May 2026 15:27:44 -0700 Subject: [PATCH 072/119] add the missing @PolyShrink annotations in nested classes. Co-authored-by: Copilot --- .../share/classes/java/util/Collections.java | 26 ++++++++++--------- .../classes/java/util/LinkedHashMap.java | 6 ++--- .../share/classes/java/util/Properties.java | 9 ++++--- .../java/util/ReverseOrderSortedMapView.java | 11 +++++--- .../share/classes/java/util/TreeMap.java | 10 +++---- .../util/concurrent/ConcurrentHashMap.java | 4 +-- .../concurrent/ConcurrentSkipListMap.java | 8 +++--- 7 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 1702a0129ac9..a1253f84ced9 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -33,8 +33,10 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -3087,7 +3089,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - public @IteratorPolyMod Set keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink SynchronizedMap this) { synchronized (mutex) { if (keySet==null) keySet = new SynchronizedSet<>(m.keySet(), mutex); @@ -3096,7 +3098,7 @@ public void clear() { } @SideEffectFree - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { synchronized (mutex) { if (entrySet==null) entrySet = new SynchronizedSet<>(m.entrySet(), mutex); @@ -3104,7 +3106,7 @@ public void clear() { } } - public @IteratorPolyMod Collection values() { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink SynchronizedMap this) { synchronized (mutex) { if (values==null) values = new SynchronizedCollection<>(m.values(), mutex); @@ -3394,19 +3396,19 @@ public NavigableMap descendingMap() { } } - public @IteratorPolyMod NavigableSet keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink SynchronizedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod NavigableSet navigableKeySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } @SideEffectFree - public @IteratorPolyMod NavigableSet descendingKeySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } @@ -4185,8 +4187,8 @@ private String badValueMsg(Object value) { public V get(Object key) { return m.get(key); } public V remove(Object key) { return m.remove(key); } public void clear() { m.clear(); } - public @IteratorPolyMod Set keySet() { return m.keySet(); } - public @IteratorPolyMod Collection values() { return m.values(); } + public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink CheckedMap this) { return m.keySet(); } + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink CheckedMap this) { return m.values(); } public boolean equals(Object o) { return o == this || m.equals(o); } public int hashCode() { return m.hashCode(); } public String toString() { return m.toString(); } @@ -4221,7 +4223,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); return entrySet; @@ -4713,17 +4715,17 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - public @IteratorPolyMod NavigableSet keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink CheckedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod NavigableSet navigableKeySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink CheckedNavigableMap this) { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - public @IteratorPolyMod NavigableSet descendingKeySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink CheckedNavigableMap this) { return checkedNavigableSet(nm.descendingKeySet(), keyType); } diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index c29665112620..07fa1bf131b4 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -1229,15 +1229,15 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); } - public @IteratorPolyMod Set keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink ReversedLinkedHashMapView this) { return base.sequencedKeySet().reversed(); } - public @IteratorPolyMod Collection values() { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ReversedLinkedHashMapView this) { return base.sequencedValues().reversed(); } - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 3e09b33cc6f3..4db57dd587c4 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -27,6 +27,9 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -1395,18 +1398,18 @@ public synchronized String toString() { } @Override - public @IteratorPolyMod Set<@KeyFor("this") Object> keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrink Properties this) { return Collections.synchronizedSet(map.keySet(), this); } @Override - public @IteratorPolyMod Collection values() { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink Properties this) { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable Properties this) { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 8218273b4b1b..c8b1d7a8b200 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -26,6 +26,9 @@ package java.util; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.Pure; /** @@ -98,7 +101,7 @@ public int size() { return base.size(); } - public @IteratorPolyMod Set keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE public Iterator iterator() { return descendingKeyIterator(base); } @@ -109,7 +112,7 @@ public int size() { }; } - public @IteratorPolyMod Collection values() { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ReverseOrderSortedMapView this) { return new AbstractCollection<>() { // inherit add(), which throws UOE public Iterator iterator() { return descendingValueIterator(base); } @@ -120,7 +123,7 @@ public int size() { }; } - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE public Iterator> iterator() { return descendingEntryIterator(base); } @@ -395,7 +398,7 @@ public String toString() { return ReverseOrderSortedMapView.toString(this, entryIterator()); } - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable Submap this) { return new AbstractSet<>() { public Iterator> iterator() { return entryIterator(); diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 4e9d79f22bc6..406c810c3f43 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -2054,18 +2054,18 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - public final @IteratorPolyMod NavigableSet navigableKeySet() { + public final @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink NavigableSubMap this) { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } - public final @IteratorPolyMod Set keySet() { + public final @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink NavigableSubMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod NavigableSet descendingKeySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink NavigableSubMap this) { return descendingMap().navigableKeySet(); } @@ -2391,7 +2391,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); } @@ -2484,7 +2484,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 0b0741a93d8d..942562ff0ea6 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -1280,7 +1280,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyMod KeySetView<@KeyFor({"this"}) K,V> keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrink ConcurrentHashMap this) { KeySetView ks; if ((ks = keySet) != null) return ks; return keySet = new KeySetView(this, null); @@ -4678,7 +4678,7 @@ public final boolean retainAll(Collection extends CollectionView + public static final class KeySetView extends CollectionView implements Set, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; @SuppressWarnings("serial") // Conditionally serializable diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 9788b066fb51..7480b0704159 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -3011,27 +3011,27 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ - public @IteratorPolyMod NavigableSet keySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod NavigableSet navigableKeySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } - public @IteratorPolyMod Collection values() { + public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink SubMap this) { Values vs; if ((vs = valuesView) != null) return vs; return valuesView = new Values<>(this); } @SideEffectFree - public @IteratorPolyMod Set> entrySet() { + public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink SubMap this) { EntrySet es; if ((es = entrySetView) != null) return es; return entrySetView = new EntrySet(this); From 702b67b4229043a40acb1063a6449fe2e8314fc9 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 7 May 2026 16:07:21 -0700 Subject: [PATCH 073/119] fully annotated properties.java and reverseOrderSortedMapView.java --- .../share/classes/java/util/Properties.java | 34 +++++++++------- .../java/util/ReverseOrderSortedMapView.java | 39 +++++++++++-------- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 4db57dd587c4..8706a6351ff3 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -26,9 +26,13 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nullness.qual.KeyFor; @@ -157,7 +161,7 @@ * @author Xueming Shen * @since 1.0 */ -@AnnotatedFor({"index", "lock", "nullness", "propkey"}) +@AnnotatedFor({"index", "lock", "nullness", "propkey", "modifiability"}) public class Properties extends Hashtable { /** * use serialVersionUID from JDK 1.1.X for interoperability @@ -1370,25 +1374,25 @@ public boolean containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object k @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized Object put(Object key, Object value) { + public synchronized Object put(@Growable @Replaceable Properties this, Object key, Object value) { return map.put(key, value); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized Object remove(@GuardSatisfied @Nullable @UnknownSignedness Object key) { + public synchronized Object remove(@Shrinkable Properties this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { return map.remove(key); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized void putAll(Map t) { + public synchronized void putAll(@Growable @Replaceable Properties this, Map t) { map.putAll(t); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized void clear() { + public synchronized void clear(@Shrinkable Properties this) { map.clear(); } @@ -1514,58 +1518,58 @@ public synchronized void forEach(BiConsumer acti @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized void replaceAll(BiFunction function) { + public synchronized void replaceAll(@Replaceable Properties this, BiFunction function) { map.replaceAll(function); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized Object putIfAbsent(Object key, Object value) { + public synchronized Object putIfAbsent(@Growable Properties this, Object key, Object value) { return map.putIfAbsent(key, value); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { + public synchronized boolean remove(@Shrinkable Properties this, @GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return map.remove(key, value); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean replace(Object key, Object oldValue, Object newValue) { + public synchronized boolean replace(@Replaceable Properties this, Object key, Object oldValue, Object newValue) { return map.replace(key, oldValue, newValue); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized Object replace(Object key, Object value) { + public synchronized Object replace(@Replaceable Properties this, Object key, Object value) { return map.replace(key, value); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized @PolyNull Object computeIfAbsent(Object key, + public synchronized @PolyNull Object computeIfAbsent(@Growable Properties this, Object key, Function mappingFunction) { return map.computeIfAbsent(key, mappingFunction); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized @PolyNull Object computeIfPresent(Object key, + public synchronized @PolyNull Object computeIfPresent(@Shrinkable @Replaceable Properties this, Object key, BiFunction remappingFunction) { return map.computeIfPresent(key, remappingFunction); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized @PolyNull Object compute(Object key, + public synchronized @PolyNull Object compute(@Modifiable Properties this, Object key, BiFunction remappingFunction) { return map.compute(key, remappingFunction); } @Override @DoesNotUnrefineReceiver("modifiability") - public synchronized @Nullable Object merge(Object key, Object value, + public synchronized @Nullable Object merge(@Modifiable Properties this, Object key, Object value, BiFunction remappingFunction) { return map.merge(key, value, remappingFunction); } @@ -1577,7 +1581,7 @@ public synchronized Object replace(Object key, Object value) { protected void rehash() { /* no-op */ } @Override - public synchronized Object clone() { + public synchronized @Modifiable Object clone() { Properties clone = (Properties) cloneHashtable(); clone.map = new ConcurrentHashMap<>(map); return clone; diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index c8b1d7a8b200..cab0d012ea53 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -25,17 +25,22 @@ package java.util; +import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.AnnotatedFor; /** * Provides a reversed-ordered view of a SortedMap. Not serializable. * * TODO: copy in equals and hashCode from AbstractMap */ +@AnnotatedFor({"modifiability"}) class ReverseOrderSortedMapView extends AbstractMap implements SortedMap { final SortedMap base; final Comparator cmp; @@ -65,7 +70,7 @@ public String toString() { // ========== Map ========== - public void clear() { + public void clear(@Shrinkable ReverseOrderSortedMapView this) { base.clear(); } @@ -85,15 +90,15 @@ public boolean isEmpty() { return base.isEmpty(); } - public V put(K key, V value) { + public V put(@Growable @Replaceable ReverseOrderSortedMapView this, K key, V value) { return base.put(key, value); } - public void putAll(Map m) { + public void putAll(@Growable @Replaceable ReverseOrderSortedMapView this, Map m) { base.putAll(m); } - public V remove(Object key) { + public V remove(@Shrinkable ReverseOrderSortedMapView this, Object key) { return base.remove(key); } @@ -156,19 +161,19 @@ public Map.Entry lastEntry() { return base.firstEntry(); } - public Map.Entry pollFirstEntry() { + public Map.Entry pollFirstEntry(@Shrinkable ReverseOrderSortedMapView this) { return base.pollLastEntry(); } - public Map.Entry pollLastEntry() { + public Map.Entry pollLastEntry(@Shrinkable ReverseOrderSortedMapView this) { return base.pollFirstEntry(); } - public V putFirst(K k, V v) { + public V putFirst(@Growable @Replaceable ReverseOrderSortedMapView this, K k, V v) { return base.putLast(k, v); } - public V putLast(K k, V v) { + public V putLast(@Growable @Replaceable ReverseOrderSortedMapView this, K k, V v) { return base.putFirst(k, v); } @@ -179,7 +184,7 @@ public Comparator comparator() { return cmp; } - public SortedMap subMap(K fromKey, K toKey) { + public @PolyModifiable SortedMap subMap(@PolyModifiable ReverseOrderSortedMapView this, K fromKey, K toKey) { if (cmp.compare(fromKey, toKey) <= 0) { return new Submap(fromKey, toKey); } else { @@ -187,11 +192,11 @@ public SortedMap subMap(K fromKey, K toKey) { } } - public SortedMap headMap(K toKey) { + public @PolyModifiable SortedMap headMap(@PolyModifiable ReverseOrderSortedMapView this, K toKey) { return new Submap(null, toKey); } - public SortedMap tailMap(K fromKey) { + public @PolyModifiable SortedMap tailMap(@PolyModifiable ReverseOrderSortedMapView this, K fromKey) { return new Submap(fromKey, null); } @@ -276,7 +281,7 @@ static class ViewEntry implements Map.Entry { public K getKey() { return key; } public V getValue() { return value; } - public V setValue(V newValue) { return map.put(key, newValue); } + public V setValue(@Replaceable ViewEntry this, V newValue) { return map.put(key, newValue); } public boolean equals(Object o) { return o instanceof Map.Entry e @@ -415,14 +420,14 @@ public int size() { }; } - public V put(K key, V value) { + public V put(@Growable @Replaceable Submap this, K key, V value) { if (aboveHead(key) && belowTail(key)) return base.put(key, value); else throw new IllegalArgumentException(); } - public V remove(Object o) { + public V remove(@Shrinkable Submap this, Object o) { @SuppressWarnings("unchecked") K key = (K) o; if (aboveHead(key) && belowTail(key)) @@ -454,7 +459,7 @@ public K lastKey() { return last.getKey(); } - public SortedMap subMap(K from, K to) { + public @PolyModifiable SortedMap subMap(@PolyModifiable Submap this, K from, K to) { if (aboveHead(from) && belowTail(from) && aboveHead(to) && belowTail(to) && cmp.compare(from, to) <= 0) { @@ -464,14 +469,14 @@ public SortedMap subMap(K from, K to) { } } - public SortedMap headMap(K to) { + public @PolyModifiable SortedMap headMap(@PolyModifiable Submap this, K to) { if (aboveHead(to) && belowTail(to)) return new Submap(head, to); else throw new IllegalArgumentException(); } - public SortedMap tailMap(K from) { + public @PolyModifiable SortedMap tailMap(@PolyModifiable Submap this, K from) { if (aboveHead(from) && belowTail(from)) return new Submap(from, tail); else From c81d4b825e5fd1b2975c825fa0d4e7bc56c73fa0 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Fri, 15 May 2026 15:18:29 -0700 Subject: [PATCH 074/119] add @IteratorPolyMod to methods whoes implementation uses iterator's modification method. --- .../classes/java/util/AbstractCollection.java | 9 +++++---- .../share/classes/java/util/AbstractList.java | 3 ++- .../java/util/AbstractSequentialList.java | 9 +++++---- .../share/classes/java/util/AbstractSet.java | 3 ++- .../share/classes/java/util/Collection.java | 3 ++- .../share/classes/java/util/Collections.java | 20 +++++++++---------- .../share/classes/java/util/List.java | 5 +++-- .../java/util/SequencedCollection.java | 5 +++-- 8 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index f68628dc305e..d9a560c3645b 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -304,7 +305,7 @@ public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { * @throws NullPointerException {@inheritDoc} */ @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) { @@ -399,7 +400,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Coll * @see #contains(Object) */ @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -435,7 +436,7 @@ public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollecti * @see #contains(Object) */ @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -465,7 +466,7 @@ public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink AbstractCollecti * @throws UnsupportedOperationException {@inheritDoc} */ @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { + public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { it.next(); diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index 6fc9e1f15dc4..e769954393a3 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -643,7 +644,7 @@ public int hashCode(@UnknownModifiability @GuardSatisfied AbstractList this) * @param toIndex index after last element to be removed */ @DoesNotUnrefineReceiver("modifiability") - protected void removeRange(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i thi * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E set(@Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public E set(@IteratorPolyMod @Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { ListIterator e = listIterator(index); E oldVal = e.next(); @@ -161,7 +162,7 @@ public E set(@Replaceable @GuardSatisfied AbstractSequentialList this, int in * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public void add(@Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public void add(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { listIterator(index).add(element); } catch (NoSuchElementException exc) { @@ -186,7 +187,7 @@ public void add(@Growable @GuardSatisfied AbstractSequentialList this, int in * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { + public E remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { try { ListIterator e = listIterator(index); E outCast = e.next(); @@ -229,7 +230,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public boolean addAll(@Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { + public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { try { boolean modified = false; ListIterator e1 = listIterator(index); diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index b78c499ed229..ba2fe04bc001 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -26,6 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.Nullable; @@ -178,7 +179,7 @@ public int hashCode(@UnknownModifiability @GuardSatisfied AbstractSet this) { * @see #contains(Object) */ @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @GuardSatisfied AbstractSet this, Collection c) { + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index d61920d8cf76..cbb96ee15828 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -623,7 +624,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, Predicate filter) { + default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index a1253f84ced9..b7a3e95e0846 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -177,7 +177,7 @@ private Collections() { * @see List#sort(Comparator) */ @SuppressWarnings("unchecked") - public static > void sort(@Replaceable List list) { + public static > void sort(@IteratorPolyMod @Replaceable List list) { list.sort(null); } @@ -211,7 +211,7 @@ public static > void sort(@Replaceable List l * @see List#sort(Comparator) */ @SuppressWarnings({"unchecked", "rawtypes"}) - public static void sort(@Replaceable List list, @Nullable Comparator c) { + public static void sort(@IteratorPolyMod @Replaceable List list, @Nullable Comparator c) { list.sort(c); } @@ -417,7 +417,7 @@ else if (cmp > 0) * @see List#reversed List.reversed */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void reverse(@Replaceable @GuardSatisfied List list) { + public static void reverse(@IteratorPolyMod @Replaceable @GuardSatisfied List list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i list) { * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the {@code set} operation. */ - public static void shuffle(@Replaceable @GuardSatisfied List list) { + public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); // harmless race. @@ -487,7 +487,7 @@ public static void shuffle(@Replaceable @GuardSatisfied List list) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void shuffle(@Replaceable List list, Random rnd) { + public static void shuffle(@IteratorPolyMod @Replaceable List list, Random rnd) { shuffle(list, (RandomGenerator) rnd); } @@ -516,7 +516,7 @@ public static void shuffle(@Replaceable List list, Random rnd) { * @since 21 */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void shuffle(@Replaceable @GuardSatisfied List list, RandomGenerator rnd) { + public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List list, RandomGenerator rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) @@ -583,7 +583,7 @@ private static void swap(Object[] arr, int i, int j) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void fill(@Replaceable @GuardSatisfied List list, T obj) { + public static void fill(@IteratorPolyMod @Replaceable @GuardSatisfied List list, T obj) { int size = list.size(); if (size < FILL_THRESHOLD || list instanceof RandomAccess) { @@ -616,7 +616,7 @@ public static void fill(@Replaceable @GuardSatisfied List list, T * @throws UnsupportedOperationException if the destination list's * list-iterator does not support the {@code set} operation. */ - public static void copy(@Replaceable List dest, @UnknownModifiability List src) { + public static void copy(@IteratorPolyMod @Replaceable List dest, @UnknownModifiability List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -844,7 +844,7 @@ public static T max(@UnknownModifiability Collection coll, @Nul * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static void rotate(@Replaceable @GuardSatisfied List list, int distance) { + public static void rotate(@IteratorPolyMod @Replaceable @GuardSatisfied List list, int distance) { if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) rotate1(list, distance); else @@ -908,7 +908,7 @@ private static void rotate2(List list, int distance) { * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static boolean replaceAll(@Replaceable List list, @Nullable T oldVal, T newVal) { + public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, @Nullable T oldVal, T newVal) { boolean result = false; int size = list.size(); if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index a15f9314a485..940be356cd1b 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -34,6 +34,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -484,7 +485,7 @@ public interface List extends SequencedCollection { * (optional) * @since 1.8 */ - default void replaceAll(@Replaceable List this, UnaryOperator operator) { + default void replaceAll(@IteratorPolyMod @Replaceable List this, UnaryOperator operator) { Objects.requireNonNull(operator); final ListIterator li = this.listIterator(); while (li.hasNext()) { @@ -552,7 +553,7 @@ default void replaceAll(@Replaceable List this, UnaryOperator operator) { * @since 1.8 */ @SuppressWarnings({"unchecked", "rawtypes"}) - default void sort(@Replaceable List this, Comparator c) { + default void sort(@IteratorPolyMod @Replaceable List this, Comparator c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator i = this.listIterator(); diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 3f722060ae60..5d606fa07939 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; @@ -185,7 +186,7 @@ default E getLast() { * does not support this operation */ @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@Shrinkable SequencedCollection this) { + default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.iterator(); E e = it.next(); it.remove(); @@ -208,7 +209,7 @@ default E removeFirst(@Shrinkable SequencedCollection this) { * does not support this operation */ @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@Shrinkable SequencedCollection this) { + default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); E e = it.next(); it.remove(); From a9c64441b9bb143db6e8dab7a4f01441d1dab90b Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Fri, 15 May 2026 16:15:07 -0700 Subject: [PATCH 075/119] Remove unnecessary `echo` commands --- .azure/azure-pipelines.yml | 1 - .azure/azure-pipelines.yml.m4 | 1 - .github/workflows/ci.yml | 1 - 3 files changed, 3 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index faf84061d065..c6c0ba503497 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -75,7 +75,6 @@ jobs: git config --global core.protectNTFS false cd ../jdk21u git diff --exit-code - echo $? displayName: clone-related-jdk21u - bash: | cd ../jdk21u && git status diff --git a/.azure/azure-pipelines.yml.m4 b/.azure/azure-pipelines.yml.m4 index 8dd5ec8fca13..e8c82d94eceb 100644 --- a/.azure/azure-pipelines.yml.m4 +++ b/.azure/azure-pipelines.yml.m4 @@ -78,7 +78,6 @@ jobs: git config --global core.protectNTFS false cd ../jdk21u git diff --exit-code - echo $? displayName: clone-related-jdk21u - bash: | cd ../jdk21u && git status diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9edbcd9d155b..351e3c7f0ab8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,6 @@ jobs: git config --global core.protectNTFS false cd ../jdk21u git diff --exit-code - echo $? - name: git merge plan run: | cd ../jdk21u && git status From bf051f904262cc8a89c974df66a39ec33fdc457e Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Fri, 15 May 2026 17:14:08 -0700 Subject: [PATCH 076/119] Reinstate return type --- src/java.base/share/classes/java/util/ArrayList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 4ced6e5c85f1..bd2813409fd6 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -385,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public @Modifiable @IteratorPolyMod clone(@GuardSatisfied ArrayList this) { + public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); From 107996ba78761327f5bd3ca4e15a275047039b19 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 17 May 2026 16:28:52 -0700 Subject: [PATCH 077/119] update checker jar --- checker-qual.jar | Bin 290638 -> 291006 bytes .../checker/builder/qual/CalledMethods.java | 2 +- .../formatter/qual/ConversionCategory.java | 10 +++++----- .../checker/index/qual/LengthOf.java | 2 +- .../modifiability/qual/IteratorPolyMod.java | 6 +++--- .../modifiability/qual/Modifiable.java | 4 ++-- .../qual/UnknownIteratorPolyMod.java | 2 +- .../modifiability/qual/Unmodifiable.java | 4 ++-- .../nonempty/qual/EnsuresNonEmptyIf.java | 2 +- .../checker/signature/qual/README.md | 7 +++++++ 10 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/signature/qual/README.md diff --git a/checker-qual.jar b/checker-qual.jar index 2307f392bb16d457f805a0aa1f5a9a1ed67d0f90..4fc8dd802bb4a45a9be1cb8f115c7d5cbb6b6481 100644 GIT binary patch delta 14520 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 delta 13980 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 * format("Test %1$f %1$d", null); @@ -107,8 +107,8 @@ public enum ConversionCategory { NULL(null), /** - * Use if a parameter is not used by the formatter. This is seldomly needed, and indicates an - * error in most cases. For example: + * Use if a parameter is not used by the formatter. This is seldom needed, and indicates an error + * in most cases. For example: * *
    *   format("Test %1$s %3$s", "a","unused","b");
@@ -223,7 +223,7 @@ public static boolean isSubsetOf(ConversionCategory a, ConversionCategory b) {
       new ConversionCategory[] {CHAR, INT, FLOAT, TIME, CHAR_AND_INT, INT_AND_TIME, NULL};
 
   /**
-   * Returns the intersection of two categories. This is seldomly needed.
+   * Returns the intersection of two categories. This is seldom needed.
    *
    * 
* @@ -274,7 +274,7 @@ public static ConversionCategory intersect(ConversionCategory a, ConversionCateg new ConversionCategory[] {NULL, CHAR_AND_INT, INT_AND_TIME, CHAR, INT, FLOAT, TIME}; /** - * Returns the union of two categories. This is seldomly needed. + * Returns the union of two categories. This is seldom needed. * *
* diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/LengthOf.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/LengthOf.java index 53adb1af1d4a..980d9796c8a0 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/LengthOf.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/LengthOf.java @@ -13,7 +13,7 @@ * detail that may change in the future, when this type may be used to implement more precise * refinements. * - *

The usual use case for the {@code LengthOf} annotation is in the defintions of custom + *

The usual use case for the {@code LengthOf} annotation is in the definitions of custom * collections. Consider the signature of java.lang.String#length(): * *

diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java
index 32f327fb02a0..d5d8ef9253b7 100644
--- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java
+++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java
@@ -8,9 +8,9 @@
 import org.checkerframework.framework.qual.SubtypeOf;
 
 /**
- * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} method
- * preserves the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has
- * type {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any
+ * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} method preserves
+ * the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has type
+ * {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any
  * collection whose type is {@code @UnknownIteratorPolyMod}, its iterator is always
  * {@code @Unshrinkable}.
  *
diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java
index 537f47bfada7..861c92453b59 100644
--- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java
+++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java
@@ -12,8 +12,8 @@
  * {@link UnsupportedOperationException}.
  *
  * 

As an exception, {@code @Modifiable} means {@code @Unknown*} if the type does not support a - * given category of operation; for example, {@Modifiable Iterator} means - * {@code @UnknownGrow @UnknownShrink @Replaceable Iterator}.) + * given category of operation; for example, {@code @Modifiable Iterator} means + * {@code @UnknownGrow @Shrinkable @UnknownReplace Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java index 23746c289a4a..4c359545002e 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java @@ -13,7 +13,7 @@ * *

This is the default qualifier for unannotated types. * - * @see #IteratorPolyMod + * @see IteratorPolyMod * @checker_framework.manual #modifiability-checker Modifiability Checker */ @Documented diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index 56f430ac40ca..37618672a08a 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -12,8 +12,8 @@ * UnsupportedOperationException}. * *

As an exception, {@code @Unmodifiable} means {@code @Unknown*} if the type does not support a - * given category of operation; for example, {@Unmodifiable Iterator} means - * {@code @UnknownGrow @UnknownShrink @Unreplaceable Iterator}.) + * given category of operation; for example, {@code @Unmodifiable Iterator} means + * {@code @UnknownGrow @Unshrinkable @UnknownReplace Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmptyIf.java b/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmptyIf.java index af97ce2509f8..56be2b326f4d 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmptyIf.java +++ b/src/java.base/share/classes/org/checkerframework/checker/nonempty/qual/EnsuresNonEmptyIf.java @@ -71,7 +71,7 @@ /** * A wrapper annotation that makes the {@link EnsuresNonEmptyIf} annotation repeatable. * - *

Programmers generally do not need to write ths. It is created by Java when a programmer + *

Programmers generally do not need to write this. It is created by Java when a programmer * writes more than one {@link EnsuresNonEmptyIf} annotation at the same location. */ @Retention(RetentionPolicy.RUNTIME) diff --git a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/README.md b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/README.md new file mode 100644 index 000000000000..6d12616e023f --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/README.md @@ -0,0 +1,7 @@ +# No `@QualifierForLiteral` annotations + +These type qualifiers have no `@QualifierForLiteral` annotations. Instead, they +use the regular expressions in +[reflection-util](https://github.com/plume-lib/reflection-util/)'s +[`SignatureRegexes` +class](https://github.com/plume-lib/reflection-util/blob/master/src/main/java/org/plumelib/reflection/SignatureRegexes.java). From 8ad1831f39f8234910544fa2f5a12e70b9718416 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 18 May 2026 00:03:22 -0700 Subject: [PATCH 078/119] rename unknownMod to maybeMod. --- checker-qual.jar | Bin 291006 -> 290947 bytes .../classes/java/util/AbstractCollection.java | 17 +++---- .../share/classes/java/util/AbstractList.java | 11 ++-- .../share/classes/java/util/AbstractMap.java | 17 +++---- .../java/util/AbstractSequentialList.java | 3 +- .../share/classes/java/util/AbstractSet.java | 5 +- .../share/classes/java/util/Collection.java | 27 +++++----- .../share/classes/java/util/Collections.java | 47 +++++++++--------- .../share/classes/java/util/HashMap.java | 1 - .../share/classes/java/util/HashSet.java | 1 - .../classes/java/util/LinkedHashSet.java | 1 - .../share/classes/java/util/List.java | 27 +++++----- .../share/classes/java/util/Map.java | 27 +++++----- .../share/classes/java/util/Set.java | 23 ++++----- .../java/util/concurrent/ConcurrentMap.java | 5 +- .../checker/modifiability/qual/Growable.java | 2 +- .../modifiability/qual/IteratorPolyMod.java | 4 +- .../qual/{UnknownGrow.java => MaybeGrow.java} | 2 +- ...PolyMod.java => MaybeIteratorPolyMod.java} | 2 +- ...odifiability.java => MaybeModifiable.java} | 10 ++-- ...{UnknownReplace.java => MaybeReplace.java} | 2 +- .../{UnknownShrink.java => MaybeShrink.java} | 2 +- .../modifiability/qual/Modifiable.java | 4 +- .../checker/modifiability/qual/PolyGrow.java | 2 +- .../modifiability/qual/PolyReplace.java | 2 +- .../modifiability/qual/PolyShrink.java | 2 +- .../modifiability/qual/Replaceable.java | 2 +- .../modifiability/qual/Shrinkable.java | 2 +- .../modifiability/qual/Ungrowable.java | 2 +- .../modifiability/qual/Unmodifiable.java | 4 +- .../modifiability/qual/Unreplaceable.java | 2 +- .../modifiability/qual/Unshrinkable.java | 2 +- 32 files changed, 123 insertions(+), 137 deletions(-) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnknownGrow.java => MaybeGrow.java} (96%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnknownIteratorPolyMod.java => MaybeIteratorPolyMod.java} (94%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnknownModifiability.java => MaybeModifiable.java} (60%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnknownReplace.java => MaybeReplace.java} (96%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnknownShrink.java => MaybeShrink.java} (96%) diff --git a/checker-qual.jar b/checker-qual.jar index 4fc8dd802bb4a45a9be1cb8f115c7d5cbb6b6481..83bc90c1e12ece18cb4d55b108cd9c11b33fe8ed 100644 GIT binary patch delta 12784 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 UpACdGiPfLr;R)A+mmj?U2UrX}bN~PV delta 12798 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 diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index d9a560c3645b..accc7b384066 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -35,7 +35,6 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -105,9 +104,9 @@ protected AbstractCollection() { * @return an iterator over the elements contained in this collection */ @SideEffectFree - public abstract @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty AbstractCollection this); + public abstract @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractCollection this); @Pure - public abstract @NonNegative int size(@UnknownModifiability @GuardSatisfied AbstractCollection this); + public abstract @NonNegative int size(@GuardSatisfied AbstractCollection this); /** * {@inheritDoc} @@ -117,7 +116,7 @@ protected AbstractCollection() { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - public boolean isEmpty(@UnknownModifiability @GuardSatisfied AbstractCollection this) { + public boolean isEmpty(@GuardSatisfied AbstractCollection this) { return size() == 0; } @@ -133,7 +132,7 @@ public boolean isEmpty(@UnknownModifiability @GuardSatisfied AbstractCollection< */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - public boolean contains(@UnknownModifiability @GuardSatisfied AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) @@ -171,7 +170,7 @@ public boolean contains(@UnknownModifiability @GuardSatisfied AbstractCollection * }

*/ @SideEffectFree - public @PolyNull @PolySigned Object[] toArray(@UnknownModifiability AbstractCollection<@PolyNull @PolySigned E> this) { + public @PolyNull @PolySigned Object[] toArray(AbstractCollection<@PolyNull @PolySigned E> this) { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator it = iterator(); @@ -212,7 +211,7 @@ public boolean contains(@UnknownModifiability @GuardSatisfied AbstractCollection * @throws NullPointerException {@inheritDoc} */ @SuppressWarnings("unchecked") - public @Nullable T [] toArray(@UnknownModifiability @PolyNull T [] a) { + public @Nullable T [] toArray(@PolyNull T [] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : @@ -342,7 +341,7 @@ public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Ab * @see #contains(Object) */ @Pure - public boolean containsAll(@UnknownModifiability @GuardSatisfied AbstractCollection this, @GuardSatisfied Collection c) { + public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSatisfied Collection c) { for (Object e : c) if (!contains(e)) return false; @@ -488,7 +487,7 @@ public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Abstra * @return a string representation of this collection */ @SideEffectFree - public String toString(@UnknownModifiability @GuardSatisfied AbstractCollection this) { + public String toString(@GuardSatisfied AbstractCollection this) { Iterator it = iterator(); if (! it.hasNext()) return "[]"; diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index e769954393a3..f085367e048d 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -36,7 +36,6 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -152,7 +151,7 @@ public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Pure - public abstract E get(@UnknownModifiability @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index); + public abstract E get(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index); /** * {@inheritDoc} @@ -221,7 +220,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In */ @Pure @StaticallyExecutable - public @GTENegativeOne int indexOf(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { + public @GTENegativeOne int indexOf(@GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(); if (o==null) { while (it.hasNext()) @@ -249,7 +248,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In */ @Pure @StaticallyExecutable - public @GTENegativeOne int lastIndexOf(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { + public @GTENegativeOne int lastIndexOf(@GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(size()); if (o==null) { while (it.hasPrevious()) @@ -585,7 +584,7 @@ static void subListRangeCheck(int fromIndex, int toIndex, int size) { * @return {@code true} if the specified object is equal to this list */ @Pure - public boolean equals(@UnknownModifiability @GuardSatisfied AbstractList this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@GuardSatisfied AbstractList this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; if (!(o instanceof List)) @@ -613,7 +612,7 @@ public boolean equals(@UnknownModifiability @GuardSatisfied AbstractList this * @return the hash code value for this list */ @Pure - public int hashCode(@UnknownModifiability @GuardSatisfied AbstractList this) { + public int hashCode(@GuardSatisfied AbstractList this) { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 7600b786e4b2..ce2ecf5905b8 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -36,7 +36,6 @@ import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -116,7 +115,7 @@ protected AbstractMap() { * This implementation returns {@code entrySet().size()}. */ @Pure - public @NonNegative int size(@UnknownModifiability @GuardSatisfied AbstractMap this) { + public @NonNegative int size(@GuardSatisfied AbstractMap this) { return entrySet().size(); } @@ -128,7 +127,7 @@ protected AbstractMap() { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - public boolean isEmpty(@UnknownModifiability @GuardSatisfied AbstractMap this) { + public boolean isEmpty(@GuardSatisfied AbstractMap this) { return size() == 0; } @@ -146,7 +145,7 @@ public boolean isEmpty(@UnknownModifiability @GuardSatisfied AbstractMap t * @throws NullPointerException {@inheritDoc} */ @Pure - public boolean containsValue(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object value) { + public boolean containsValue(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object value) { Iterator> i = entrySet().iterator(); if (value==null) { while (i.hasNext()) { @@ -180,7 +179,7 @@ public boolean containsValue(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { @@ -213,7 +212,7 @@ public boolean containsKey(@UnknownModifiability @GuardSatisfied AbstractMap this, @UnknownSignedness @GuardSatisfied Object key) { + public @Nullable V get(@GuardSatisfied AbstractMap this, @UnknownSignedness @GuardSatisfied Object key) { Iterator> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { @@ -542,7 +541,7 @@ public boolean contains(@UnknownSignedness Object v) { * @return {@code true} if the specified object is equal to this map */ @Pure - public boolean equals(@UnknownModifiability @GuardSatisfied AbstractMap this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@GuardSatisfied AbstractMap this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; @@ -589,7 +588,7 @@ public boolean equals(@UnknownModifiability @GuardSatisfied AbstractMap th * @see Set#equals(Object) */ @Pure - public int hashCode(@UnknownModifiability@GuardSatisfied AbstractMap this) { + public int hashCode(@GuardSatisfied AbstractMap this) { int h = 0; for (Entry entry : entrySet()) h += entry.hashCode(); @@ -609,7 +608,7 @@ public int hashCode(@UnknownModifiability@GuardSatisfied AbstractMap this) * @return a string representation of this map */ @SideEffectFree - public String toString(@UnknownModifiability @GuardSatisfied AbstractMap this) { + public String toString(@GuardSatisfied AbstractMap this) { Iterator> i = entrySet().iterator(); if (! i.hasNext()) return "{}"; diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index de2e0a11bcb4..0f54212474a9 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -34,7 +34,6 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -104,7 +103,7 @@ protected AbstractSequentialList() { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Pure - public E get(@UnknownModifiability @GuardSatisfied AbstractSequentialList this, int index) { + public E get(@GuardSatisfied AbstractSequentialList this, int index) { try { return listIterator(index).next(); } catch (NoSuchElementException exc) { diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index ba2fe04bc001..2cb271b8f946 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -28,7 +28,6 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; @@ -96,7 +95,7 @@ protected AbstractSet() { * @return {@code true} if the specified object is equal to this set */ @Pure - public boolean equals(@UnknownModifiability @GuardSatisfied AbstractSet this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@GuardSatisfied AbstractSet this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; @@ -130,7 +129,7 @@ public boolean equals(@UnknownModifiability @GuardSatisfied AbstractSet this, * @see Set#equals(Object) */ @Pure - public int hashCode(@UnknownModifiability @GuardSatisfied AbstractSet this) { + public int hashCode(@GuardSatisfied AbstractSet this) { int h = 0; Iterator i = iterator(); while (i.hasNext()) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index cbb96ee15828..f329dd591378 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -34,7 +34,6 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -293,7 +292,7 @@ public interface Collection extends Iterable { * @return the number of elements in this collection */ @Pure - @NonNegative int size(@UnknownModifiability @GuardSatisfied Collection this); + @NonNegative int size(@GuardSatisfied Collection this); /** * Returns {@code true} if this collection contains no elements. @@ -302,7 +301,7 @@ public interface Collection extends Iterable { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@UnknownModifiability @GuardSatisfied Collection this); + boolean isEmpty(@GuardSatisfied Collection this); /** * Returns {@code true} if this collection contains the specified element. @@ -325,7 +324,7 @@ public interface Collection extends Iterable { "(though I think a nicer specification would be to return false in that case)"}) @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@UnknownModifiability @GuardSatisfied Collection this, @GuardSatisfied @UnknownSignedness Object o); + boolean contains(@GuardSatisfied Collection this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns an iterator over the elements in this collection. There are no @@ -336,7 +335,7 @@ public interface Collection extends Iterable { * @return an {@code Iterator} over the elements in this collection */ @SideEffectFree - @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Collection this); + @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Collection this); /** * Returns an array containing all of the elements in this collection. @@ -365,7 +364,7 @@ public interface Collection extends Iterable { "methods, because the most useful type for toArray is not expressible", "in the surface syntax that the nullness annotations support."}) @SideEffectFree - @PolyNull @PolySigned Object[] toArray(@UnknownModifiability Collection<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(Collection<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this collection; @@ -418,7 +417,7 @@ public interface Collection extends Iterable { * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ - @Nullable T [] toArray(@UnknownModifiability Collection this, @PolyNull T[] a); + @Nullable T [] toArray(Collection this, @PolyNull T[] a); /** * Returns an array containing all of the elements in this collection, @@ -456,7 +455,7 @@ public interface Collection extends Iterable { * @since 11 */ @SideEffectFree - default T[] toArray(@UnknownModifiability Collection this, IntFunction generator) { + default T[] toArray(Collection this, IntFunction generator) { return toArray(generator.apply(0)); } @@ -544,7 +543,7 @@ default T[] toArray(@UnknownModifiability Collection this, IntFunction this, @GuardSatisfied Collection c); + boolean containsAll(@GuardSatisfied Collection this, @GuardSatisfied Collection c); /** * Adds all of the elements in the specified collection to this collection @@ -709,7 +708,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t * @see List#equals(Object) */ @Pure - boolean equals(@UnknownModifiability @GuardSatisfied Collection this, @GuardSatisfied @Nullable @UnknownSignedness Object o); + boolean equals(@GuardSatisfied Collection this, @GuardSatisfied @Nullable @UnknownSignedness Object o); /** * Returns the hash code value for this collection. While the @@ -727,7 +726,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t * @see Object#equals(Object) */ @Pure - int hashCode(@UnknownModifiability @GuardSatisfied Collection this); + int hashCode(@GuardSatisfied Collection this); /** * Creates a {@link Spliterator} over the elements in this collection. @@ -781,7 +780,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t */ @SideEffectFree @Override - default Spliterator spliterator(@UnknownModifiability Collection this) { + default Spliterator spliterator(Collection this) { return Spliterators.spliterator(this, 0); } @@ -801,7 +800,7 @@ default Spliterator spliterator(@UnknownModifiability Collection this) { * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - default @PolyNonEmpty Stream stream(@UnknownModifiability @PolyNonEmpty Collection this) { + default @PolyNonEmpty Stream stream(@PolyNonEmpty Collection this) { return StreamSupport.stream(spliterator(), false); } @@ -823,7 +822,7 @@ default Spliterator spliterator(@UnknownModifiability Collection this) { * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - default Stream parallelStream(@UnknownModifiability Collection this) { + default Stream parallelStream(Collection this) { return StreamSupport.stream(spliterator(), true); } } diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index b7a3e95e0846..70907b4838f3 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -35,7 +35,6 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; import org.checkerframework.checker.modifiability.qual.Replaceable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -248,7 +247,7 @@ public static void sort(@IteratorPolyMod @Replaceable List list, @Nullabl * with the elements of the list. */ public static - int binarySearch(@UnknownModifiability List> list, T key) { + int binarySearch(List> list, T key) { if (list instanceof RandomAccess || list.size()> lis } private static - int indexedBinarySearch(@UnknownModifiability List> list, T key) { + int indexedBinarySearch(List> list, T key) { int low = 0; int high = list.size()-1; @@ -276,7 +275,7 @@ else if (cmp > 0) } private static - int iteratorBinarySearch(@UnknownModifiability List> list, T key) + int iteratorBinarySearch(List> list, T key) { int low = 0; int high = list.size()-1; @@ -352,7 +351,7 @@ private static T get(ListIterator i, int index) { * elements of the list using this comparator. */ @SuppressWarnings("unchecked") - public static int binarySearch(@UnknownModifiability List list, T key, @Nullable Comparator c) { + public static int binarySearch(List list, T key, @Nullable Comparator c) { if (c==null) return binarySearch((List>) list, key); @@ -362,7 +361,7 @@ public static int binarySearch(@UnknownModifiability List list, return Collections.iteratorBinarySearch(list, key, c); } - private static int indexedBinarySearch(@UnknownModifiability List l, T key, Comparator c) { + private static int indexedBinarySearch(List l, T key, Comparator c) { int low = 0; int high = l.size()-1; @@ -381,7 +380,7 @@ else if (cmp > 0) return -(low + 1); // key not found } - private static int iteratorBinarySearch(@UnknownModifiability List l, T key, Comparator c) { + private static int iteratorBinarySearch(List l, T key, Comparator c) { int low = 0; int high = l.size()-1; ListIterator i = l.listIterator(); @@ -616,7 +615,7 @@ public static void fill(@IteratorPolyMod @Replaceable @GuardSatisfied List void copy(@IteratorPolyMod @Replaceable List dest, @UnknownModifiability List src) { + public static void copy(@IteratorPolyMod @Replaceable List dest, List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -659,7 +658,7 @@ public static void copy(@IteratorPolyMod @Replaceable List dest, */ @Pure @StaticallyExecutable - public static > T min(@UnknownModifiability Collection coll) { + public static > T min(Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); @@ -697,7 +696,7 @@ public static > T min(@UnknownModifiabi @SuppressWarnings({"unchecked", "rawtypes"}) @Pure @StaticallyExecutable - public static T min(@UnknownModifiability Collection coll, @Nullable Comparator comp) { + public static T min(Collection coll, @Nullable Comparator comp) { if (comp==null) return (T)min((Collection>) coll); @@ -736,7 +735,7 @@ public static T min(@UnknownModifiability Collection coll, @Nul */ @Pure @StaticallyExecutable - public static > T max(@UnknownModifiability Collection coll) { + public static > T max(Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); @@ -774,7 +773,7 @@ public static > T max(@UnknownModifiabi @SuppressWarnings({"unchecked", "rawtypes"}) @Pure @StaticallyExecutable - public static T max(@UnknownModifiability Collection coll, @Nullable Comparator comp) { + public static T max(Collection coll, @Nullable Comparator comp) { if (comp==null) return (T)max((Collection>) coll); @@ -970,7 +969,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @Pure @StaticallyExecutable - public static @GTENegativeOne int indexOfSubList(@UnknownModifiability @GuardSatisfied List source, @GuardSatisfied List target) { + public static @GTENegativeOne int indexOfSubList(@GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; @@ -1025,7 +1024,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @Pure @StaticallyExecutable - public static @GTENegativeOne int lastIndexOfSubList(@UnknownModifiability @GuardSatisfied List source, @GuardSatisfied List target) { + public static @GTENegativeOne int lastIndexOfSubList(@GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; @@ -1089,7 +1088,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @SuppressWarnings("unchecked") @SideEffectFree - public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Collection c) { + public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@PolyGrowShrink @PolyNonEmpty Collection c) { if (c.getClass() == UnmodifiableCollection.class) { return (Collection) c; } @@ -1318,7 +1317,7 @@ public E removeLast() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@UnknownModifiability @PolyNonEmpty Set s) { + public static @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@PolyNonEmpty Set s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSet.class) { return (Set) s; @@ -1411,7 +1410,7 @@ public SequencedSet reversed() { * returned. * @return an unmodifiable view of the specified sorted set. */ - public static @Unmodifiable @PolyNonEmpty SortedSet unmodifiableSortedSet(@UnknownModifiability @PolyNonEmpty SortedSet s) { + public static @Unmodifiable @PolyNonEmpty SortedSet unmodifiableSortedSet(@PolyNonEmpty SortedSet s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSortedSet.class) { return s; @@ -1472,7 +1471,7 @@ public SortedSet tailSet(E fromElement) { * @return an unmodifiable view of the specified navigable set * @since 1.8 */ - public static @Unmodifiable @PolyNonEmpty NavigableSet unmodifiableNavigableSet(@UnknownModifiability @PolyNonEmpty NavigableSet s) { + public static @Unmodifiable @PolyNonEmpty NavigableSet unmodifiableNavigableSet(@PolyNonEmpty NavigableSet s) { if (s.getClass() == UnmodifiableNavigableSet.class) { return s; } @@ -1578,7 +1577,7 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @return an unmodifiable view of the specified list. */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty List unmodifiableList(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty List list) { + public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty List unmodifiableList(@PolyGrowShrink @PolyNonEmpty List list) { if (list.getClass() == UnmodifiableList.class || list.getClass() == UnmodifiableRandomAccessList.class) { return (List) list; } @@ -1753,7 +1752,7 @@ private Object writeReplace() { * @return an unmodifiable view of the specified map. */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyNonEmpty Map unmodifiableMap(@UnknownModifiability @PolyNonEmpty Map m) { + public static @Unmodifiable @PolyNonEmpty Map unmodifiableMap(@PolyNonEmpty Map m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableMap.class) { return (Map) m; @@ -2195,7 +2194,7 @@ public V putLast(K k, V v) { * @return an unmodifiable view of the specified sorted map. */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyNonEmpty SortedMap unmodifiableSortedMap(@UnknownModifiability @PolyNonEmpty SortedMap m) { + public static @Unmodifiable @PolyNonEmpty SortedMap unmodifiableSortedMap(@PolyNonEmpty SortedMap m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableSortedMap.class) { return (SortedMap) m; @@ -2251,7 +2250,7 @@ public SortedMap tailMap(K fromKey) * @since 1.8 */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyNonEmpty NavigableMap unmodifiableNavigableMap(@UnknownModifiability @PolyNonEmpty NavigableMap m) { + public static @Unmodifiable @PolyNonEmpty NavigableMap unmodifiableNavigableMap(@PolyNonEmpty NavigableMap m) { if (m.getClass() == UnmodifiableNavigableMap.class) { return (NavigableMap) m; } @@ -6078,7 +6077,7 @@ static boolean eq(Object o1, Object o2) { * @throws NullPointerException if {@code c} is null * @since 1.5 */ - public static @NonNegative int frequency(@UnknownModifiability Collection c, @Nullable Object o) { + public static @NonNegative int frequency(Collection c, @Nullable Object o) { int result = 0; if (o == null) { for (Object e : c) @@ -6130,7 +6129,7 @@ static boolean eq(Object o1, Object o2) { * (optional) * @since 1.5 */ - public static boolean disjoint(@UnknownModifiability Collection c1, @UnknownModifiability Collection c2) { + public static boolean disjoint(Collection c1, Collection c2) { // The collection to be used for contains(). Preference is given to // the collection who's contains() has lower O() complexity. Collection contains = c2; diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 7bbb0fa8ead3..f2ae4d9c8b84 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -35,7 +35,6 @@ import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 51241b4ee3a4..b0ddc63979c6 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -33,7 +33,6 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index c592552080f2..0a1b1342550b 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -29,7 +29,6 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.dataflow.qual.Deterministic; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 940be356cd1b..5ef08bc0f975 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -39,7 +39,6 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -182,7 +181,7 @@ public interface List extends SequencedCollection { * @return the number of elements in this list */ @Pure - @NonNegative int size(@UnknownModifiability @GuardSatisfied List this); + @NonNegative int size(@GuardSatisfied List this); /** * Returns {@code true} if this list contains no elements. @@ -191,7 +190,7 @@ public interface List extends SequencedCollection { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@UnknownModifiability @GuardSatisfied List this); + boolean isEmpty(@GuardSatisfied List this); /** * Returns {@code true} if this list contains the specified element. @@ -210,7 +209,7 @@ public interface List extends SequencedCollection { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@UnknownModifiability @GuardSatisfied List this, @UnknownSignedness Object o); + boolean contains(@GuardSatisfied List this, @UnknownSignedness Object o); /** * Returns an iterator over the elements in this list in proper sequence. @@ -218,7 +217,7 @@ public interface List extends SequencedCollection { * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - @PolyGrowShrink @UnknownModifiability @PolyNonEmpty Iterator iterator(@PolyGrowShrink @UnknownModifiability @PolyNonEmpty List this); + @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty List this); /** * Returns an array containing all of the elements in this list in proper @@ -237,7 +236,7 @@ public interface List extends SequencedCollection { * @see Arrays#asList(Object[]) */ @SideEffectFree - @PolyNull @PolySigned Object[] toArray(@UnknownModifiability List<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(List<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this list in @@ -278,7 +277,7 @@ public interface List extends SequencedCollection { * this list * @throws NullPointerException if the specified array is null */ - @Nullable T[] toArray(@UnknownModifiability List this, @PolyNull T[] a); + @Nullable T[] toArray(List this, @PolyNull T[] a); // Modification Operations @@ -356,7 +355,7 @@ public interface List extends SequencedCollection { * @see #contains(Object) */ @Pure - boolean containsAll(@UnknownModifiability @GuardSatisfied List this, Collection c); + boolean containsAll(@GuardSatisfied List this, Collection c); /** * Appends all of the elements in the specified collection to the end of @@ -590,7 +589,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this, @Nullable Object o); + boolean equals(@GuardSatisfied List this, @Nullable Object o); /** * Returns the hash code value for this list. The hash code of a list @@ -610,7 +609,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this); + int hashCode(@GuardSatisfied List this); // Positional Access Operations @@ -624,7 +623,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator= size()}) */ @Pure - E get(@UnknownModifiability @GuardSatisfied List this, @IndexFor({"this"}) int index); + E get(@GuardSatisfied List this, @IndexFor({"this"}) int index); /** * Replaces the element at the specified position in this list with the @@ -708,7 +707,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparatoroptional) */ @Pure - @GTENegativeOne int indexOf(@UnknownModifiability @GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); + @GTENegativeOne int indexOf(@GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns the index of the last occurrence of the specified element @@ -728,7 +727,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparatoroptional) */ @Pure - @GTENegativeOne int lastIndexOf(@UnknownModifiability @GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); + @GTENegativeOne int lastIndexOf(@GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); // List Iterators @@ -1246,7 +1245,7 @@ default List reversed() { * @throws NullPointerException if coll is null, or if it contains any nulls * @since 10 */ - static @Unmodifiable @PolyNonEmpty List copyOf(@UnknownModifiability @PolyNonEmpty Collection coll) { + static @Unmodifiable @PolyNonEmpty List copyOf(@PolyNonEmpty Collection coll) { return ImmutableCollections.listCopy(coll); } } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index bbea6545fa71..6b988abe6cd6 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -36,7 +36,6 @@ import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -205,7 +204,7 @@ public interface Map { * @return the number of key-value mappings in this map */ @Pure - @NonNegative int size(@UnknownModifiability @GuardSatisfied Map this); + @NonNegative int size(@GuardSatisfied Map this); /** * Returns {@code true} if this map contains no key-value mappings. @@ -214,7 +213,7 @@ public interface Map { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@UnknownModifiability @GuardSatisfied Map this); + boolean isEmpty(@GuardSatisfied Map this); /** * Returns {@code true} if this map contains a mapping for the specified @@ -235,7 +234,7 @@ public interface Map { @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @EnsuresNonEmptyIf(result=true, expression={"this"}) @Pure - boolean containsKey(@UnknownModifiability @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); + boolean containsKey(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); /** * Returns {@code true} if this map maps one or more keys to the @@ -255,7 +254,7 @@ public interface Map { */ @EnsuresNonEmptyIf(result=true, expression={"this"}) @Pure - boolean containsValue(@UnknownModifiability @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); + boolean containsValue(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); /** * Returns the value to which the specified key is mapped, @@ -282,7 +281,7 @@ public interface Map { * does not permit null keys ({@linkplain Collection##optional-restrictions optional}) */ @Pure - @Nullable V get(@UnknownModifiability @GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); + @Nullable V get(@GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); // Modification Operations @@ -512,7 +511,7 @@ interface Entry { * removed from the backing map. */ @Pure - K getKey(Map.@UnknownModifiability @GuardSatisfied Entry this); + K getKey(Map.@GuardSatisfied Entry this); /** * Returns the value corresponding to this entry. If the mapping @@ -525,7 +524,7 @@ interface Entry { * removed from the backing map. */ @Pure - V getValue(Map.@UnknownModifiability @GuardSatisfied Entry this); + V getValue(Map.@GuardSatisfied Entry this); /** * Replaces the value corresponding to this entry with the specified @@ -569,7 +568,7 @@ interface Entry { * entry */ @Pure - boolean equals(Map.@UnknownModifiability @GuardSatisfied Entry this, @GuardSatisfied @Nullable Object o); + boolean equals(Map.@GuardSatisfied Entry this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this map entry. The hash code @@ -588,7 +587,7 @@ interface Entry { * @see #equals(Object) */ @Pure - int hashCode(Map.@UnknownModifiability @GuardSatisfied Entry this); + int hashCode(Map.@GuardSatisfied Entry this); /** * Returns a comparator that compares {@link Map.Entry} in natural order on key. @@ -689,7 +688,7 @@ public static Comparator> comparingByValue(Comparator - Map.@Unmodifiable Entry copyOf(Map.@UnknownModifiability Entry e) { + Map.@Unmodifiable Entry copyOf(Map.Entry e) { Objects.requireNonNull(e); if (e instanceof KeyValueHolder) { return (Map.Entry) e; @@ -714,7 +713,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @Nullable Object o); + boolean equals(@GuardSatisfied Map this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this map. The hash code of a map is @@ -730,7 +729,7 @@ public static Comparator> comparingByValue(Comparator this); + int hashCode(@GuardSatisfied Map this); // Defaultable methods @@ -1820,7 +1819,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal * @since 10 */ @SuppressWarnings({"rawtypes","unchecked"}) - static @Unmodifiable @PolyNonEmpty Map copyOf(@UnknownModifiability @PolyNonEmpty Map map) { + static @Unmodifiable @PolyNonEmpty Map copyOf(@PolyNonEmpty Map map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map)map; } else if (map.isEmpty()) { // Implicit nullcheck of map diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index b8d6a3878110..3f285d07ddb6 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -31,7 +31,6 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -147,7 +146,7 @@ public interface Set extends Collection { * @return the number of elements in this set (its cardinality) */ @Pure - @NonNegative int size(@UnknownModifiability @GuardSatisfied Set this); + @NonNegative int size(@GuardSatisfied Set this); /** * Returns {@code true} if this set contains no elements. @@ -156,7 +155,7 @@ public interface Set extends Collection { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@UnknownModifiability @GuardSatisfied Set this); + boolean isEmpty(@GuardSatisfied Set this); /** * Returns {@code true} if this set contains the specified element. @@ -175,7 +174,7 @@ public interface Set extends Collection { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@UnknownModifiability @GuardSatisfied Set this, @GuardSatisfied @UnknownSignedness Object o); + boolean contains(@GuardSatisfied Set this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns an iterator over the elements in this set. The elements are @@ -185,7 +184,7 @@ public interface Set extends Collection { * @return an iterator over the elements in this set */ @SideEffectFree - @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Set this); + @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Set this); /** * Returns an array containing all of the elements in this set. @@ -204,7 +203,7 @@ public interface Set extends Collection { * @return an array containing all the elements in this set */ @SideEffectFree - @PolyNull @PolySigned Object[] toArray(@UnknownModifiability Set<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(Set<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this set; the @@ -248,7 +247,7 @@ public interface Set extends Collection { * set * @throws NullPointerException if the specified array is null */ - @Nullable T [] toArray(@UnknownModifiability Set this, @PolyNull T[] a); + @Nullable T [] toArray(Set this, @PolyNull T[] a); // Modification Operations @@ -335,7 +334,7 @@ public interface Set extends Collection { * @see #contains(Object) */ @Pure - boolean containsAll(@UnknownModifiability @GuardSatisfied Set this, @GuardSatisfied Collection c); + boolean containsAll(@GuardSatisfied Set this, @GuardSatisfied Collection c); /** * Adds all of the elements in the specified collection to this set if @@ -437,7 +436,7 @@ public interface Set extends Collection { * @return {@code true} if the specified object is equal to this set */ @Pure - boolean equals(@UnknownModifiability @GuardSatisfied Set this, @GuardSatisfied @Nullable Object o); + boolean equals(@GuardSatisfied Set this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this set. The hash code of a set is @@ -453,7 +452,7 @@ public interface Set extends Collection { * @see Set#equals(Object) */ @Pure - int hashCode(@UnknownModifiability @GuardSatisfied Set this); + int hashCode(@GuardSatisfied Set this); /** * Creates a {@code Spliterator} over the elements in this set. @@ -480,7 +479,7 @@ public interface Set extends Collection { */ @Override @DoesNotUnrefineReceiver("modifiability") - default Spliterator spliterator(@UnknownModifiability Set this) { + default Spliterator spliterator(Set this) { return Spliterators.spliterator(this, Spliterator.DISTINCT); } @@ -768,7 +767,7 @@ default Spliterator spliterator(@UnknownModifiability Set this) { * @since 10 */ @SuppressWarnings("unchecked") - static @Unmodifiable @PolyNonEmpty Set copyOf(@UnknownModifiability @PolyNonEmpty Collection coll) { + static @Unmodifiable @PolyNonEmpty Set copyOf(@PolyNonEmpty Collection coll) { if (coll instanceof ImmutableCollections.AbstractImmutableSet) { return (Set)coll; } else if (coll.isEmpty()) { // Implicit nullcheck of coll diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 82451837df80..2e08ab6b86ad 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -40,7 +40,6 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -98,7 +97,7 @@ public interface ConcurrentMap this,Object key, V defaultValue) { + default V getOrDefault(ConcurrentMap this,Object key, V defaultValue) { V v; return ((v = get(key)) != null) ? v : defaultValue; } @@ -122,7 +121,7 @@ default V getOrDefault(@UnknownModifiability ConcurrentMap this,Object key, * @since 1.8 */ @Override - default void forEach(@UnknownModifiability ConcurrentMap this,BiConsumer action) { + default void forEach(ConcurrentMap this,BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { K k; diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java index 5c2b1b7315c1..2c8041469c75 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownGrow.class) +@SubtypeOf(MaybeGrow.class) public @interface Growable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java index d5d8ef9253b7..8ad422162e21 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java @@ -11,7 +11,7 @@ * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} method preserves * the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has type * {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any - * collection whose type is {@code @UnknownIteratorPolyMod}, its iterator is always + * collection whose type is {@code @MaybeIteratorPolyMod}, its iterator is always * {@code @Unshrinkable}. * * @checker_framework.manual #modifiability-checker Modifiability Checker @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownIteratorPolyMod.class) +@SubtypeOf(MaybeIteratorPolyMod.class) public @interface IteratorPolyMod {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrow.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrow.java index c71e04417b1c..92789632cc75 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownGrow.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrow.java @@ -21,4 +21,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface UnknownGrow {} +public @interface MaybeGrow {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java similarity index 94% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java index 4c359545002e..30f794ba7973 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownIteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java @@ -21,4 +21,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface UnknownIteratorPolyMod {} +public @interface MaybeIteratorPolyMod {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java similarity index 60% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java index 502805c4a134..5a9a53e8f45c 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownModifiability.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java @@ -7,16 +7,16 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @UnknownGrow @UnknownShrink @UnknownReplace}. Represents an - * unknown or arbitrary modifiability capability; the checker cannot determine whether the - * collection is growable, shrinkable, or replaceable. + * Convenience alias meaning {@code @MaybeGrow @MaybeShrink @MaybeReplace}. Represents an unknown or + * arbitrary modifiability capability; the checker cannot determine whether the collection is + * growable, shrinkable, or replaceable. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @UnknownGrow @UnknownShrink @UnknownReplace} on each annotated type. + * {@code @MaybeGrow @MaybeShrink @MaybeReplace} on each annotated type. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -public @interface UnknownModifiability {} +public @interface MaybeModifiable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplace.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplace.java index 164002371c5b..70fbbb939007 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownReplace.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplace.java @@ -22,4 +22,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface UnknownReplace {} +public @interface MaybeReplace {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrink.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrink.java index 68f5918995e3..d5edc2ccf523 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnknownShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrink.java @@ -22,4 +22,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface UnknownShrink {} +public @interface MaybeShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java index 861c92453b59..2d5f571deb64 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -11,9 +11,9 @@ * operation (growing, shrinking, or replacing) on this collection will not result in throwing * {@link UnsupportedOperationException}. * - *

As an exception, {@code @Modifiable} means {@code @Unknown*} if the type does not support a + *

As an exception, {@code @Modifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Modifiable Iterator} means - * {@code @UnknownGrow @Shrinkable @UnknownReplace Iterator}. + * {@code @MaybeGrow @Shrinkable @MaybeReplace Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java index 3a4d5b43fbf8..ef00276e8d64 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@PolymorphicQualifier(UnknownGrow.class) +@PolymorphicQualifier(MaybeGrow.class) public @interface PolyGrow {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java index eb6e7ac5af7d..f8664f330bca 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@PolymorphicQualifier(UnknownReplace.class) +@PolymorphicQualifier(MaybeReplace.class) public @interface PolyReplace {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java index b491d8626f99..f35eece7403b 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@PolymorphicQualifier(UnknownShrink.class) +@PolymorphicQualifier(MaybeShrink.class) public @interface PolyShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java index bc6199b61f62..2d7c2e7c6926 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownReplace.class) +@SubtypeOf(MaybeReplace.class) public @interface Replaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java index cabe5a275869..1d7fddbeea03 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownShrink.class) +@SubtypeOf(MaybeShrink.class) public @interface Shrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java index 24348a29d853..d160c345b0e4 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownGrow.class) +@SubtypeOf(MaybeGrow.class) public @interface Ungrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index 37618672a08a..53ea1e4066ff 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -11,9 +11,9 @@ * mutating operation (growing, shrinking, or replacing) may throw {@link * UnsupportedOperationException}. * - *

As an exception, {@code @Unmodifiable} means {@code @Unknown*} if the type does not support a + *

As an exception, {@code @Unmodifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Unmodifiable Iterator} means - * {@code @UnknownGrow @Unshrinkable @UnknownReplace Iterator}. + * {@code @MaybeGrow @Unshrinkable @MaybeReplace Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java index 1f58bc15625f..32dc1f2e6a47 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownReplace.class) +@SubtypeOf(MaybeReplace.class) public @interface Unreplaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java index 1b97e46abbdf..347db2a2b656 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(UnknownShrink.class) +@SubtypeOf(MaybeShrink.class) public @interface Unshrinkable {} From 75abeb499bc859ae4b7959fc2aa35a326958a92d Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 18 May 2026 00:04:38 -0700 Subject: [PATCH 079/119] remove annotation in iterable. --- src/java.base/share/classes/java/lang/Iterable.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Iterable.java b/src/java.base/share/classes/java/lang/Iterable.java index 25b8ac62b59d..2b0cacbbfbc6 100644 --- a/src/java.base/share/classes/java/lang/Iterable.java +++ b/src/java.base/share/classes/java/lang/Iterable.java @@ -25,7 +25,6 @@ package java.lang; import org.checkerframework.checker.index.qual.PolyGrowShrink; -import org.checkerframework.checker.modifiability.qual.UnknownModifiability; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.common.aliasing.qual.NonLeaked; import org.checkerframework.framework.qual.AnnotatedFor; @@ -52,7 +51,7 @@ public interface Iterable { * * @return an Iterator. */ - @UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterator iterator(@UnknownModifiability @PolyGrowShrink @PolyNonEmpty Iterable this); + @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Iterable this); /** * Performs the given action for each element of the {@code Iterable} From dd5291a7e7fff49814ce6982cca5ea1e86004410 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Mon, 18 May 2026 19:29:24 -0700 Subject: [PATCH 080/119] Fix package of import --- src/java.base/share/classes/java/util/AbstractCollection.java | 2 +- src/java.base/share/classes/java/util/AbstractList.java | 2 +- src/java.base/share/classes/java/util/AbstractMap.java | 2 +- src/java.base/share/classes/java/util/AbstractQueue.java | 2 +- src/java.base/share/classes/java/util/AbstractSet.java | 2 +- src/java.base/share/classes/java/util/ArrayDeque.java | 2 +- src/java.base/share/classes/java/util/ArrayList.java | 2 +- src/java.base/share/classes/java/util/Collection.java | 2 +- src/java.base/share/classes/java/util/Collections.java | 2 +- src/java.base/share/classes/java/util/Deque.java | 2 +- src/java.base/share/classes/java/util/EnumSet.java | 2 +- src/java.base/share/classes/java/util/HashMap.java | 2 +- src/java.base/share/classes/java/util/HashSet.java | 2 +- src/java.base/share/classes/java/util/Hashtable.java | 2 +- src/java.base/share/classes/java/util/IdentityHashMap.java | 2 +- src/java.base/share/classes/java/util/Iterator.java | 2 +- src/java.base/share/classes/java/util/JumboEnumSet.java | 2 +- src/java.base/share/classes/java/util/LinkedHashMap.java | 2 +- src/java.base/share/classes/java/util/LinkedHashSet.java | 2 +- src/java.base/share/classes/java/util/LinkedList.java | 2 +- src/java.base/share/classes/java/util/List.java | 2 +- src/java.base/share/classes/java/util/ListIterator.java | 2 +- src/java.base/share/classes/java/util/Map.java | 2 +- src/java.base/share/classes/java/util/NavigableMap.java | 2 +- src/java.base/share/classes/java/util/NavigableSet.java | 2 +- src/java.base/share/classes/java/util/PrimitiveIterator.java | 2 +- src/java.base/share/classes/java/util/Properties.java | 2 +- src/java.base/share/classes/java/util/Queue.java | 2 +- src/java.base/share/classes/java/util/RegularEnumSet.java | 2 +- src/java.base/share/classes/java/util/SequencedCollection.java | 2 +- src/java.base/share/classes/java/util/SequencedMap.java | 2 +- src/java.base/share/classes/java/util/SequencedSet.java | 2 +- src/java.base/share/classes/java/util/Set.java | 2 +- src/java.base/share/classes/java/util/SortedMap.java | 2 +- src/java.base/share/classes/java/util/SortedSet.java | 2 +- src/java.base/share/classes/java/util/Stack.java | 2 +- src/java.base/share/classes/java/util/TreeMap.java | 2 +- src/java.base/share/classes/java/util/TreeSet.java | 2 +- src/java.base/share/classes/java/util/Vector.java | 2 +- src/java.base/share/classes/java/util/WeakHashMap.java | 2 +- .../share/classes/java/util/concurrent/ArrayBlockingQueue.java | 2 +- .../share/classes/java/util/concurrent/ConcurrentHashMap.java | 2 +- .../classes/java/util/concurrent/ConcurrentLinkedDeque.java | 2 +- .../classes/java/util/concurrent/ConcurrentLinkedQueue.java | 2 +- .../classes/java/util/concurrent/ConcurrentSkipListMap.java | 2 +- .../classes/java/util/concurrent/ConcurrentSkipListSet.java | 2 +- .../classes/java/util/concurrent/CopyOnWriteArrayList.java | 2 +- .../share/classes/java/util/concurrent/CopyOnWriteArraySet.java | 2 +- .../share/classes/java/util/concurrent/DelayQueue.java | 2 +- .../share/classes/java/util/concurrent/LinkedBlockingDeque.java | 2 +- .../share/classes/java/util/concurrent/LinkedBlockingQueue.java | 2 +- .../share/classes/java/util/concurrent/LinkedTransferQueue.java | 2 +- .../classes/java/util/concurrent/PriorityBlockingQueue.java | 2 +- .../share/classes/java/util/concurrent/SynchronousQueue.java | 2 +- 54 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index accc7b384066..c806fa237ae1 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -42,7 +42,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index f085367e048d..7e81260494d0 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -44,7 +44,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.value.qual.StaticallyExecutable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index ce2ecf5905b8..04b3662a2d54 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -44,7 +44,7 @@ import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index d50e5506893c..fd57373972dc 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -42,7 +42,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index 2cb271b8f946..6e0b3588eb41 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 0a3f9864e14d..db5a2b16c971 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -53,7 +53,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index bd2813409fd6..c496fa453ea2 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -47,7 +47,7 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.value.qual.StaticallyExecutable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index f329dd591378..f68d1bc7b16c 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -43,7 +43,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 70907b4838f3..8f443c3308f8 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -51,7 +51,7 @@ import org.checkerframework.common.value.qual.ArrayLen; import org.checkerframework.common.value.qual.MinLen; import org.checkerframework.common.value.qual.StaticallyExecutable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 44b5dd360984..060a5842b7a1 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -48,7 +48,7 @@ import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index eaed5d30f237..d6c0d6ed1508 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.framework.qual.AnnotatedFor; import jdk.internal.access.SharedSecrets; diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index f2ae4d9c8b84..0e727adacedd 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -46,7 +46,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index b0ddc63979c6..9cfb6518bbf7 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -40,7 +40,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index f9ed6296137b..e1542a0665be 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -45,7 +45,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index f696043ef1d1..e60676dbcb2c 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -43,7 +43,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index b767443e391c..3016db9216d3 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/JumboEnumSet.java b/src/java.base/share/classes/java/util/JumboEnumSet.java index 72dc66eb2072..21c9a851b21a 100644 --- a/src/java.base/share/classes/java/util/JumboEnumSet.java +++ b/src/java.base/share/classes/java/util/JumboEnumSet.java @@ -35,7 +35,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 07fa1bf131b4..992c63c9a4d0 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -42,7 +42,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 0a1b1342550b..7bf974006445 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.dataflow.qual.Deterministic; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index d2ecaa17bb68..811c3c99017f 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -46,7 +46,7 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.value.qual.StaticallyExecutable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 5ef08bc0f975..2137108864ea 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -48,7 +48,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/ListIterator.java b/src/java.base/share/classes/java/util/ListIterator.java index b92d41fd16f1..f30650384a17 100644 --- a/src/java.base/share/classes/java/util/ListIterator.java +++ b/src/java.base/share/classes/java/util/ListIterator.java @@ -33,7 +33,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 6b988abe6cd6..798de4e29f5c 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -49,7 +49,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.aliasing.qual.NonLeaked; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 374870daaa8e..0742ba165b37 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -43,7 +43,7 @@ import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 3eff9dee501c..f62300e9a349 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -41,7 +41,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/PrimitiveIterator.java b/src/java.base/share/classes/java/util/PrimitiveIterator.java index 150564d3774a..5536b06b2c73 100644 --- a/src/java.base/share/classes/java/util/PrimitiveIterator.java +++ b/src/java.base/share/classes/java/util/PrimitiveIterator.java @@ -26,7 +26,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.nonempty.qual.NonEmpty; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.framework.qual.AnnotatedFor; import java.util.function.Consumer; diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 8706a6351ff3..3b9af3271012 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -40,7 +40,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.propkey.qual.PropertyKey; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index 1d4f0b21191e..7d91f1e7a656 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -44,7 +44,7 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/RegularEnumSet.java b/src/java.base/share/classes/java/util/RegularEnumSet.java index 9b5a5e2dddaf..0fe13bdab68c 100644 --- a/src/java.base/share/classes/java/util/RegularEnumSet.java +++ b/src/java.base/share/classes/java/util/RegularEnumSet.java @@ -36,7 +36,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 5d606fa07939..9a932f875249 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index bc4585f01d23..615ab9f0622b 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.SideEffectFree; import jdk.internal.util.NullableKeyValueHolder; diff --git a/src/java.base/share/classes/java/util/SequencedSet.java b/src/java.base/share/classes/java/util/SequencedSet.java index d4bac4cd6747..c4fa139e9e41 100644 --- a/src/java.base/share/classes/java/util/SequencedSet.java +++ b/src/java.base/share/classes/java/util/SequencedSet.java @@ -25,7 +25,7 @@ package java.util; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A collection that is both a {@link SequencedCollection} and a {@link Set}. As such, diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 3f285d07ddb6..d213be1aa6e7 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -40,7 +40,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 72372e592bd7..8c120b8b1b9c 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -35,7 +35,7 @@ import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 796dee2ba8bf..1de786fae66d 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index b82161d87056..0e0ed3ea88f9 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -33,7 +33,7 @@ import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 406c810c3f43..16e10d59ddf2 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -45,7 +45,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 786be122f4c3..15837c1acc62 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -41,7 +41,7 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 54bf76f120e3..2fa58f55ba2d 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -45,7 +45,7 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.value.qual.StaticallyExecutable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index a0665a32b9f2..519da9a7c040 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -44,7 +44,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; 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 7452cfe05578..fe19d11e978e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 942562ff0ea6..72883682cb90 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -57,7 +57,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index a3427f395589..1f12eb6b14a4 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -53,7 +53,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 3502f7e5c323..4c9a49ac8941 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 7480b0704159..54c6a995c39f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -54,7 +54,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 6655663deaa3..fa70a0e9b760 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -51,7 +51,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; 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 b242e33dcf19..777938c56fd8 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -54,7 +54,7 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.value.qual.StaticallyExecutable; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; 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 84c58335c031..84bd296a346a 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -51,7 +51,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 5ff56d96dd5b..3f6af0d4eee3 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -48,7 +48,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; 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 0b3a77f0bdad..f524be2c2c3e 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; 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 da6e97349f06..092c5f47c256 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -51,7 +51,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index d034769b8315..e10695be96c2 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; 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 dec4dfc3b25d..edecdf4a91bc 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 3950b648cf02..461568f2a42d 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -50,7 +50,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; -import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; From 1a1e9027952aa4b1d8fcccb35bacf17d1883cb85 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 19 May 2026 11:27:47 -0700 Subject: [PATCH 081/119] Formatting --- src/java.base/share/classes/java/util/Hashtable.java | 2 +- src/java.base/share/classes/java/util/LinkedHashSet.java | 1 - src/java.base/share/classes/java/util/SequencedCollection.java | 2 -- src/java.base/share/classes/java/util/SortedMap.java | 2 +- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index f9ed6296137b..f1bcf163d166 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -32,9 +32,9 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; -import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 0a1b1342550b..f2ced291064b 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -33,7 +33,6 @@ import org.checkerframework.dataflow.qual.Deterministic; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; - import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 5d606fa07939..fbaae2995a11 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -25,14 +25,12 @@ package java.util; - import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.dataflow.qual.DoesNotUnrefineReceiver; import org.checkerframework.dataflow.qual.Pure; - /** * A collection that has a well-defined encounter order, that supports operations at both ends, * and that is reversible. The elements of a sequenced collection have an diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 72372e592bd7..dbb88fc1e695 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -30,8 +30,8 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrink; -import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; +import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; From c361f120748c3461f18add215e648723988895ef Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Thu, 21 May 2026 16:29:22 -0700 Subject: [PATCH 082/119] fixed collection.java to array --- src/java.base/share/classes/java/util/Collection.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 70822c1aac0d..cf08a7d6292a 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -280,7 +280,7 @@ */ @CFComment("lock/nullness: Subclasses of this interface/class may opt to prohibit null elements") -@AnnotatedFor({"lock", "nullness", "index"}) +@AnnotatedFor({"lock", "nullness", "index", "modifiability"}) public interface Collection extends Iterable { // Query Operations @@ -417,14 +417,7 @@ public interface Collection extends Iterable { * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ -<<<<<<< HEAD - @Nullable T [] toArray(Collection this, @PolyNull T[] a); -||||||| f7ef3b0183d - @SideEffectFree - @Nullable T [] toArray(@PolyNull T[] a); -======= - @Nullable T [] toArray(@PolyNull T[] a); ->>>>>>> 805ed882efc3db6c39efbf35bfa1d706ac857291 + @Nullable T[] toArray(Collection this, @PolyNull T[] a); /** * Returns an array containing all of the elements in this collection, From c84d0dfe1b758c8a35a46b7d6f3d27f137d0835f Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 21 May 2026 18:21:24 -0700 Subject: [PATCH 083/119] Fix bad merge --- src/java.base/share/classes/java/util/AbstractMap.java | 1 - src/java.base/share/classes/java/util/Deque.java | 2 -- src/java.base/share/classes/java/util/ImmutableCollections.java | 1 - src/java.base/share/classes/java/util/Properties.java | 2 -- 4 files changed, 6 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 327036430774..2427bba6be06 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -439,7 +439,6 @@ public void clear() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - @Pure public boolean contains(@UnknownSignedness Object k) { return AbstractMap.this.containsKey(k); } diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 28e28106f4b6..413f1c10a16e 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -356,7 +356,6 @@ public interface Deque extends Queue, SequencedCollection { */ @Pure @EnsuresNonEmpty("this") - @Pure E getFirst(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -369,7 +368,6 @@ public interface Deque extends Queue, SequencedCollection { */ @Pure @EnsuresNonEmpty("this") - @Pure E getLast(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java index a6ceaf0e4cb3..65f6d6f4e570 100644 --- a/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -618,7 +618,6 @@ public boolean isEmpty() { } @Override - @Pure @SuppressWarnings("unchecked") @Pure public E get(int index) { diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index b36496e8fb62..f0d16353da49 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -1511,14 +1511,12 @@ public Iterator> iterator() { @Pure @Override - @Pure public synchronized boolean equals(Object o) { return map.equals(o); } @Pure @Override - @Pure public synchronized int hashCode() { return map.hashCode(); } From 7396edfccffefc510eb26fd42e2c4ebb0c0abdd4 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 23 May 2026 12:48:58 -0700 Subject: [PATCH 084/119] Fix formatting --- .../share/classes/java/util/ArrayDeque.java | 63 ++++++++----- .../share/classes/java/util/ArrayList.java | 42 ++++++--- .../share/classes/java/util/HashMap.java | 29 +++--- .../share/classes/java/util/HashSet.java | 6 +- .../classes/java/util/LinkedHashMap.java | 45 ++++++--- .../classes/java/util/LinkedHashSet.java | 12 ++- .../share/classes/java/util/LinkedList.java | 69 +++++++++----- .../share/classes/java/util/NavigableSet.java | 9 +- .../share/classes/java/util/Properties.java | 24 +++-- .../share/classes/java/util/SortedMap.java | 3 +- .../share/classes/java/util/SortedSet.java | 9 +- .../share/classes/java/util/TreeMap.java | 21 +++-- .../share/classes/java/util/TreeSet.java | 21 +++-- .../share/classes/java/util/Vector.java | 57 ++++++++---- .../util/concurrent/ArrayBlockingQueue.java | 39 +++++--- .../util/concurrent/ConcurrentHashMap.java | 24 +++-- .../concurrent/ConcurrentLinkedDeque.java | 54 +++++++---- .../concurrent/ConcurrentLinkedQueue.java | 27 ++++-- .../concurrent/ConcurrentSkipListMap.java | 54 +++++++---- .../concurrent/ConcurrentSkipListSet.java | 18 ++-- .../util/concurrent/CopyOnWriteArraySet.java | 21 +++-- .../java/util/concurrent/DelayQueue.java | 36 ++++--- .../util/concurrent/LinkedBlockingDeque.java | 93 ++++++++++++------- .../util/concurrent/LinkedBlockingQueue.java | 36 ++++--- .../util/concurrent/LinkedTransferQueue.java | 48 ++++++---- .../concurrent/PriorityBlockingQueue.java | 42 ++++++--- .../util/concurrent/SynchronousQueue.java | 33 ++++--- 27 files changed, 622 insertions(+), 313 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 84390dd83395..5a5c34b96c7f 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -310,7 +310,8 @@ static final E nonNullElementAt(@PolyNull @PolySigned Object[] es, int i) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { if (e == null) + public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { + if (e == null) throw new NullPointerException(); final Object[] es = elements; es[head = dec(head, es.length)] = e; @@ -328,7 +329,8 @@ public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { if (e == null) + public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { + if (e == null) throw new NullPointerException(); final Object[] es = elements; es[tail] = e; @@ -348,7 +350,8 @@ public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable ArrayDeque this, Collection c) { final int s, needed; + public boolean addAll(@Growable ArrayDeque this, Collection c) { + final int s, needed; if ((needed = (s = size()) + c.size() + 1 - elements.length) > 0) grow(needed); copyElements(c); @@ -368,7 +371,8 @@ private void copyElements(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable ArrayDeque this, E e) { addFirst(e); + public boolean offerFirst(@Growable ArrayDeque this, E e) { + addFirst(e); return true; } @@ -381,7 +385,8 @@ private void copyElements(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable ArrayDeque this, E e) { addLast(e); + public boolean offerLast(@Growable ArrayDeque this, E e) { + addLast(e); return true; } @@ -390,7 +395,8 @@ private void copyElements(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollFirst(); + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + E e = pollFirst(); if (e == null) throw new NoSuchElementException(); return e; @@ -401,7 +407,8 @@ private void copyElements(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollLast(); + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + E e = pollLast(); if (e == null) throw new NoSuchElementException(); return e; @@ -409,7 +416,8 @@ private void copyElements(Collection c) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { + final Object[] es; final int h; E e = elementAt(es = elements, h = head); if (e != null) { @@ -421,7 +429,8 @@ private void copyElements(Collection c) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { + final Object[] es; final int t; E e = elementAt(es = elements, t = dec(tail, es.length)); if (e != null) @@ -477,7 +486,8 @@ public E getLast(@GuardSatisfied @NonEmpty ArrayDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { + public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o != null) { final Object[] es = elements; for (int i = head, end = tail, to = (i <= end) ? end : es.length; ; i = 0, to = end) { @@ -506,7 +516,8 @@ public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink Arra */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { + public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o != null) { final Object[] es = elements; for (int i = tail, end = head, to = (i >= end) ? end : 0; ; i = es.length, to = end) { @@ -535,7 +546,8 @@ public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Array @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied ArrayDeque this, E e) { addLast(e); + public boolean add(@Growable @GuardSatisfied ArrayDeque this, E e) { + addLast(e); return true; } @@ -550,7 +562,8 @@ public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Array */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable @GuardSatisfied ArrayDeque this, E e) { return offerLast(e); + public boolean offer(@Growable @GuardSatisfied ArrayDeque this, E e) { + return offerLast(e); } /** @@ -566,7 +579,8 @@ public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Array */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + return removeFirst(); } /** @@ -581,7 +595,8 @@ public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink Array */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { return pollFirst(); + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { + return pollFirst(); } /** @@ -626,7 +641,8 @@ public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable @GuardSatisfied ArrayDeque this, E e) { addFirst(e); + public void push(@Growable @GuardSatisfied ArrayDeque this, E e) { + addFirst(e); } /** @@ -641,7 +657,8 @@ public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { + return removeFirst(); } /** @@ -963,7 +980,8 @@ public void forEach(Consumer action) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink ArrayDeque this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink ArrayDeque this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -982,7 +1000,8 @@ public boolean removeAll(@CanShrink ArrayDeque this, Collection this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -1099,7 +1118,8 @@ public boolean contains(@GuardSatisfied ArrayDeque this, @GuardSatisfied @Nul */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return removeFirstOccurrence(o); } /** @@ -1108,7 +1128,8 @@ public boolean contains(@GuardSatisfied ArrayDeque this, @GuardSatisfied @Nul */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { circularClear(elements, head, tail); + public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayDeque this) { + circularClear(elements, head, tail); head = tail = 0; } diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 1ffec09c1a83..0ccb44c7e8ce 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -568,7 +568,8 @@ public boolean add(@Growable @GuardSatisfied ArrayList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable @GuardSatisfied ArrayList this, @NonNegative int index, E element) { rangeCheckForAdd(index); + public void add(@Growable @GuardSatisfied ArrayList this, @NonNegative int index, E element) { + rangeCheckForAdd(index); modCount++; final int s; Object[] elementData; @@ -588,7 +589,8 @@ public boolean add(@Growable @GuardSatisfied ArrayList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable ArrayList this, E element) { add(0, element); + public void addFirst(@Growable ArrayList this, E element) { + add(0, element); } /** @@ -598,7 +600,8 @@ public boolean add(@Growable @GuardSatisfied ArrayList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable ArrayList this, E element) { add(element); + public void addLast(@Growable ArrayList this, E element) { + add(element); } /** @@ -612,7 +615,8 @@ public boolean add(@Growable @GuardSatisfied ArrayList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @NonNegative int index) { Objects.checkIndex(index, size); + public E remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @NonNegative int index) { + Objects.checkIndex(index, size); final Object[] es = elementData; @SuppressWarnings("unchecked") E oldValue = (E) es[index]; @@ -629,7 +633,8 @@ public boolean add(@Growable @GuardSatisfied ArrayList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable ArrayList this) { if (size == 0) { + public E removeFirst(@Shrinkable ArrayList this) { + if (size == 0) { throw new NoSuchElementException(); } else { Object[] es = elementData; @@ -647,7 +652,8 @@ public E removeFirst(@Shrinkable ArrayList this) { if (size == 0) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable ArrayList this) { int last = size - 1; + public E removeLast(@Shrinkable ArrayList this) { + int last = size - 1; if (last < 0) { throw new NoSuchElementException(); } else { @@ -764,7 +770,8 @@ int hashCodeRange(int from, int to) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { final Object[] es = elementData; + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + final Object[] es = elementData; final int size = this.size; int i = 0; found: { @@ -801,7 +808,8 @@ private void fastRemove(Object[] es, int i) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayList this) { modCount++; + public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayList this) { + modCount++; final Object[] es = elementData; for (int to = size, i = size = 0; i < to; i++) es[i] = null; @@ -822,7 +830,8 @@ private void fastRemove(Object[] es, int i) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied ArrayList this, Collection c) { Object[] a = c.toArray(); + public boolean addAll(@Growable @GuardSatisfied ArrayList this, Collection c) { + Object[] a = c.toArray(); modCount++; int numNew = a.length; if (numNew == 0) @@ -853,7 +862,8 @@ private void fastRemove(Object[] es, int i) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied ArrayList this, @NonNegative int index, Collection c) { rangeCheckForAdd(index); + public boolean addAll(@Growable @GuardSatisfied ArrayList this, @NonNegative int index, Collection c) { + rangeCheckForAdd(index); Object[] a = c.toArray(); modCount++; @@ -945,7 +955,8 @@ private static String outOfBoundsMsg(int fromIndex, int toIndex) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink ArrayList this, Collection c) { return batchRemove(c, false, 0, size); + public boolean removeAll(@Shrinkable @CanShrink ArrayList this, Collection c) { + return batchRemove(c, false, 0, size); } /** @@ -966,7 +977,8 @@ private static String outOfBoundsMsg(int fromIndex, int toIndex) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, Collection c) { return batchRemove(c, true, 0, size); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayList this, Collection c) { + return batchRemove(c, true, 0, size); } boolean batchRemove(Collection c, boolean complement, @@ -1875,7 +1887,8 @@ private static boolean isClear(long[] bits, int i) { @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink ArrayList this, Predicate filter) { return removeIf(filter, 0, size); + public boolean removeIf(@Shrinkable @CanShrink ArrayList this, Predicate filter) { + return removeIf(filter, 0, size); } /** @@ -1938,7 +1951,8 @@ private void replaceAllRange(@Replaceable ArrayList this, UnaryOperator op @SuppressWarnings("unchecked") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void sort(@Replaceable ArrayList this, Comparator c) { final int expectedModCount = modCount; + public void sort(@Replaceable ArrayList this, Comparator c) { + final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) throw new ConcurrentModificationException(); diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 6112a0a4529a..3c8f01e98d41 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -48,11 +48,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; -// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.io.IOException; import java.io.InvalidObjectException; @@ -660,7 +659,8 @@ public boolean containsKey(@GuardSatisfied HashMap this, @GuardSatisfied @ @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied HashMap this, K key, V value) { return putVal(hash(key), key, value, false, true); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied HashMap this, K key, V value) { + return putVal(hash(key), key, value, false, true); } /** @@ -835,7 +835,8 @@ else if ((e = tab[index = (n - 1) & hash]) != null) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied HashMap this, Map m) { putMapEntries(m, true); + public void putAll(@Growable @Replaceable @GuardSatisfied HashMap this, Map m) { + putMapEntries(m, true); } /** @@ -849,7 +850,8 @@ else if ((e = tab[index = (n - 1) & hash]) != null) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Node e; + public @Nullable V remove(@Shrinkable @GuardSatisfied HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + Node e; return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value; } @@ -911,7 +913,8 @@ else if (node == p) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied HashMap this) { Node[] tab; + public void clear(@Shrinkable @GuardSatisfied HashMap this) { + Node[] tab; modCount++; if ((tab = table) != null && size > 0) { size = 0; @@ -1225,7 +1228,7 @@ public final void forEach(Consumer> action) { @Override @Pure - public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V defaultValue) { + public V getOrDefault(HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key, V defaultValue) { Node e; return (e = getNode(key)) == null ? defaultValue : e.value; } @@ -1234,19 +1237,22 @@ public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V putIfAbsent(@Growable HashMap this, K key, V value) { return putVal(hash(key), key, value, true, true); + public @Nullable V putIfAbsent(@Growable HashMap this, K key, V value) { + return putVal(hash(key), key, value, true, true); } @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return removeNode(hash(key), key, value, true, true) != null; + public boolean remove(@Shrinkable HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { + return removeNode(hash(key), key, value, true, true) != null; } @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean replace(@Replaceable HashMap this, K key, V oldValue, V newValue) { Node e; V v; + public boolean replace(@Replaceable HashMap this, K key, V oldValue, V newValue) { + Node e; V v; if ((e = getNode(key)) != null && ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) { e.value = newValue; @@ -1259,7 +1265,8 @@ public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V replace(@Replaceable HashMap this, K key, V value) { Node e; + public @Nullable V replace(@Replaceable HashMap this, K key, V value) { + Node e; if ((e = getNode(key)) != null) { V oldValue = e.value; e.value = value; diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 574168b4620d..d167f8dbd8a6 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -276,7 +276,8 @@ public boolean add(@Growable @GuardSatisfied HashSet this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied HashSet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return map.remove(o)==PRESENT; + public boolean remove(@Shrinkable @GuardSatisfied HashSet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return map.remove(o)==PRESENT; } /** @@ -285,7 +286,8 @@ public boolean add(@Growable @GuardSatisfied HashSet this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied HashSet this) { map.clear(); + public void clear(@Shrinkable @GuardSatisfied HashSet this) { + map.clear(); } /** diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 32f99dae65d0..a408dd0b707c 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -417,7 +417,8 @@ void afterNodeAccess(Node e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { try { + public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { + try { putMode = PUT_FIRST; return this.put(k, v); } finally { @@ -435,7 +436,8 @@ public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putLast(@Growable @Replaceable LinkedHashMap this, K k, V v) { try { + public V putLast(@Growable @Replaceable LinkedHashMap this, K k, V v) { + try { putMode = PUT_LAST; return this.put(k, v); } finally { @@ -590,7 +592,8 @@ public V getOrDefault(@Nullable Object key, V defaultValue) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied LinkedHashMap this) { super.clear(); + public void clear(@Shrinkable @GuardSatisfied LinkedHashMap this) { + super.clear(); head = tail = null; } @@ -1243,22 +1246,26 @@ public V get(Object key) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V put(@Growable @Replaceable ReversedLinkedHashMapView this, K key, V value) { return base.put(key, value); + public V put(@Growable @Replaceable ReversedLinkedHashMapView this, K key, V value) { + return base.put(key, value); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V remove(@Shrinkable ReversedLinkedHashMapView this, Object key) { return base.remove(key); + public V remove(@Shrinkable ReversedLinkedHashMapView this, Object key) { + return base.remove(key); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable ReversedLinkedHashMapView this, Map m) { base.putAll(m); + public void putAll(@Growable @Replaceable ReversedLinkedHashMapView this, Map m) { + base.putAll(m); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable ReversedLinkedHashMapView this) { base.clear(); + public void clear(@Shrinkable ReversedLinkedHashMapView this) { + base.clear(); } @SideEffectFree @@ -1306,22 +1313,26 @@ public void replaceAll(@Replaceable ReversedLinkedHashMapView this, BiFunct // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putIfAbsent(@Growable ReversedLinkedHashMapView this, K key, V value) { return base.putIfAbsent(key, value); + public V putIfAbsent(@Growable ReversedLinkedHashMapView this, K key, V value) { + return base.putIfAbsent(key, value); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable ReversedLinkedHashMapView this, Object key, Object value) { return base.remove(key, value); + public boolean remove(@Shrinkable ReversedLinkedHashMapView this, Object key, Object value) { + return base.remove(key, value); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean replace(@Replaceable ReversedLinkedHashMapView this, K key, V oldValue, V newValue) { return base.replace(key, oldValue, newValue); + public boolean replace(@Replaceable ReversedLinkedHashMapView this, K key, V oldValue, V newValue) { + return base.replace(key, oldValue, newValue); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V replace(@Replaceable ReversedLinkedHashMapView this, K key, V value) { return base.replace(key, value); + public V replace(@Replaceable ReversedLinkedHashMapView this, K key, V value) { + return base.replace(key, value); } @DoesNotUnrefineReceiver("modifiability") @@ -1362,22 +1373,26 @@ public Entry lastEntry() { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public Entry pollFirstEntry(@Shrinkable ReversedLinkedHashMapView this) { return base.pollLastEntry(); + public Entry pollFirstEntry(@Shrinkable ReversedLinkedHashMapView this) { + return base.pollLastEntry(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public Entry pollLastEntry(@Shrinkable ReversedLinkedHashMapView this) { return base.pollFirstEntry(); + public Entry pollLastEntry(@Shrinkable ReversedLinkedHashMapView this) { + return base.pollFirstEntry(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putFirst(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { return base.putLast(k, v); + public V putFirst(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { + return base.putLast(k, v); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putLast(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { return base.putFirst(k, v); + public V putLast(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { + return base.putFirst(k, v); } } } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index b263b7b69b7c..3fd84ab2ead8 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -257,7 +257,8 @@ LinkedHashMap map() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable LinkedHashSet this, E e) { map().putFirst(e, PRESENT); + public void addFirst(@Growable LinkedHashSet this, E e) { + map().putFirst(e, PRESENT); } /** @@ -270,7 +271,8 @@ LinkedHashMap map() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable LinkedHashSet this, E e) { map().putLast(e, PRESENT); + public void addLast(@Growable LinkedHashSet this, E e) { + map().putLast(e, PRESENT); } /** @@ -303,7 +305,8 @@ public E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable LinkedHashSet this) { return map().sequencedKeySet().removeFirst(); + public E removeFirst(@Shrinkable LinkedHashSet this) { + return map().sequencedKeySet().removeFirst(); } /** @@ -314,7 +317,8 @@ public E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable LinkedHashSet this) { return map().sequencedKeySet().removeLast(); + public E removeLast(@Shrinkable LinkedHashSet this) { + return map().sequencedKeySet().removeLast(); } /** diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index 5471d6e70de1..ae75c4276c7f 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -310,7 +310,8 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node f = first; + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + final Node f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); @@ -324,7 +325,8 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node l = last; + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + final Node l = last; if (l == null) throw new NoSuchElementException(); return unlinkLast(l); @@ -337,7 +339,8 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { linkFirst(e); + public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { + linkFirst(e); } /** @@ -349,7 +352,8 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable @GuardSatisfied LinkedList this, E e) { linkLast(e); + public void addLast(@Growable @GuardSatisfied LinkedList this, E e) { + linkLast(e); } /** @@ -389,7 +393,8 @@ public boolean contains(@GuardSatisfied LinkedList this, @GuardSatisfied @Nul @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied LinkedList this, E e) { linkLast(e); + public boolean add(@Growable @GuardSatisfied LinkedList this, E e) { + linkLast(e); return true; } @@ -409,7 +414,8 @@ public boolean contains(@GuardSatisfied LinkedList this, @GuardSatisfied @Nul @ReleasesNoLocks // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o == null) { for (Node x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); @@ -441,7 +447,8 @@ public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied LinkedList this, Collection c) { return addAll(size, c); + public boolean addAll(@Growable @GuardSatisfied LinkedList this, Collection c) { + return addAll(size, c); } /** @@ -461,7 +468,8 @@ public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, Collection c) { checkPositionIndex(index); + public boolean addAll(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, Collection c) { + checkPositionIndex(index); Object[] a = c.toArray(); int numNew = a.length; @@ -505,7 +513,8 @@ public boolean remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { // Clearing all of the links between nodes is "unnecessary", but: + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { + // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit // more than one generation // - is sure to free memory even if there is a reachable Iterator @@ -548,7 +557,8 @@ public E get(@GuardSatisfied LinkedList this, @NonNegative int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@Replaceable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkElementIndex(index); + public E set(@Replaceable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { + checkElementIndex(index); Node x = node(index); E oldVal = x.item; x.item = element; @@ -566,7 +576,8 @@ public E get(@GuardSatisfied LinkedList this, @NonNegative int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkPositionIndex(index); + public void add(@Growable @GuardSatisfied LinkedList this, @NonNegative int index, E element) { + checkPositionIndex(index); if (index == size) linkLast(element); @@ -585,7 +596,8 @@ public E get(@GuardSatisfied LinkedList this, @NonNegative int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @NonNegative int index) { checkElementIndex(index); + public E remove(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @NonNegative int index) { + checkElementIndex(index); return unlink(node(index)); } @@ -740,7 +752,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node f = first; + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { + final Node f = first; return (f == null) ? null : unlinkFirst(f); } @@ -753,7 +766,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + return removeFirst(); } /** @@ -765,7 +779,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable LinkedList this, E e) { return add(e); + public boolean offer(@Growable LinkedList this, E e) { + return add(e); } // Deque operations @@ -778,7 +793,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable LinkedList this, E e) { addFirst(e); + public boolean offerFirst(@Growable LinkedList this, E e) { + addFirst(e); return true; } @@ -791,7 +807,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable LinkedList this, E e) { addLast(e); + public boolean offerLast(@Growable LinkedList this, E e) { + addLast(e); return true; } @@ -833,7 +850,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node f = first; + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { + final Node f = first; return (f == null) ? null : unlinkFirst(f); } @@ -847,7 +865,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { final Node l = last; + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedList this) { + final Node l = last; return (l == null) ? null : unlinkLast(l); } @@ -862,7 +881,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable @GuardSatisfied LinkedList this, E e) { addFirst(e); + public void push(@Growable @GuardSatisfied LinkedList this, E e) { + addFirst(e); } /** @@ -878,7 +898,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList this) { + return removeFirst(); } /** @@ -892,7 +913,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return remove(o); + public boolean removeFirstOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return remove(o); } /** @@ -906,7 +928,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { + public boolean removeLastOccurrence(@Shrinkable @GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o == null) { for (Node x = last; x != null; x = x.prev) { if (x.item == null) { unlink(x); diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 6b6c432f8734..e35ceacea9c7 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -365,7 +365,8 @@ public interface NavigableSet extends SortedSet { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@Shrinkable NavigableSet this) { if (this.isEmpty()) { + default E removeFirst(@Shrinkable NavigableSet this) { + if (this.isEmpty()) { throw new NoSuchElementException(); } else { return this.pollFirst(); @@ -385,7 +386,8 @@ default E removeFirst(@Shrinkable NavigableSet this) { if (this.isEmpt */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@Shrinkable NavigableSet this) { if (this.isEmpty()) { + default E removeLast(@Shrinkable NavigableSet this) { + if (this.isEmpty()) { throw new NoSuchElementException(); } else { return this.pollLast(); @@ -406,6 +408,7 @@ default E removeLast(@Shrinkable NavigableSet this) { if (this.isEmpty */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyModifiable NavigableSet reversed(@PolyModifiable NavigableSet this) { return this.descendingSet(); + default @PolyModifiable NavigableSet reversed(@PolyModifiable NavigableSet this) { + return this.descendingSet(); } } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index f0d16353da49..a8f088627ccb 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -1379,25 +1379,29 @@ public boolean containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object k @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized Object put(@Growable @Replaceable Properties this, Object key, Object value) { return map.put(key, value); + public synchronized Object put(@Growable @Replaceable Properties this, Object key, Object value) { + return map.put(key, value); } @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized Object remove(@Shrinkable Properties this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { return map.remove(key); + public synchronized Object remove(@Shrinkable Properties this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + return map.remove(key); } @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void putAll(@Growable @Replaceable Properties this, Map t) { map.putAll(t); + public synchronized void putAll(@Growable @Replaceable Properties this, Map t) { + map.putAll(t); } @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void clear(@Shrinkable Properties this) { map.clear(); + public synchronized void clear(@Shrinkable Properties this) { + map.clear(); } @Override @@ -1542,25 +1546,29 @@ public synchronized void replaceAll(@Replaceable Properties this, BiFunction reversed(@PolyModifiable SortedMap this) { return ReverseOrderSortedMapView.of(this); + default @PolyModifiable SortedMap reversed(@PolyModifiable SortedMap this) { + return ReverseOrderSortedMapView.of(this); } } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 9592f52d3747..65a87c793afd 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -364,7 +364,8 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@Shrinkable SortedSet this) { E e = this.first(); + default E removeFirst(@Shrinkable SortedSet this) { + E e = this.first(); this.remove(e); return e; } @@ -383,7 +384,8 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@Shrinkable SortedSet this) { E e = this.last(); + default E removeLast(@Shrinkable SortedSet this) { + E e = this.last(); this.remove(e); return e; } @@ -400,6 +402,7 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyModifiable SortedSet reversed(@PolyModifiable SortedSet this) { return ReverseOrderSortedSetView.of(this); + default @PolyModifiable SortedSet reversed(@PolyModifiable SortedSet this) { + return ReverseOrderSortedSetView.of(this); } } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 5ffe51387413..0a63820cadd0 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -391,7 +391,8 @@ public V putLast(K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied TreeMap this, Map map) { int mapSize = map.size(); + public void putAll(@Growable @Replaceable @GuardSatisfied TreeMap this, Map map) { + int mapSize = map.size(); if (size==0 && mapSize!=0 && map instanceof SortedMap) { if (Objects.equals(comparator, ((SortedMap)map).comparator())) { ++modCount; @@ -613,13 +614,15 @@ final Entry getLowerEntry(K key) { @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied TreeMap this, K key, V value) { return put(key, value, true); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied TreeMap this, K key, V value) { + return put(key, value, true); } @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putIfAbsent(@Growable TreeMap this, K key, V value) { return put(key, value, false); + public V putIfAbsent(@Growable TreeMap this, K key, V value) { + return put(key, value, false); } /** @@ -966,7 +969,8 @@ private V mergeValue(Entry t, V value, BiFunction this, @GuardSatisfied @UnknownSignedness Object key) { Entry p = getEntry(key); + public @Nullable V remove(@Shrinkable @GuardSatisfied TreeMap this, @GuardSatisfied @UnknownSignedness Object key) { + Entry p = getEntry(key); if (p == null) return null; @@ -981,7 +985,8 @@ private V mergeValue(Entry t, V value, BiFunction this) { modCount++; + public void clear(@Shrinkable @GuardSatisfied TreeMap this) { + modCount++; size = 0; root = null; } @@ -1041,7 +1046,8 @@ private V mergeValue(Entry t, V value, BiFunction pollFirstEntry(@Shrinkable @GuardSatisfied TreeMap this) { Entry p = getFirstEntry(); + public Map.@Nullable Entry pollFirstEntry(@Shrinkable @GuardSatisfied TreeMap this) { + Entry p = getFirstEntry(); Map.Entry result = exportEntry(p); if (p != null) deleteEntry(p); @@ -1053,7 +1059,8 @@ private V mergeValue(Entry t, V value, BiFunction pollLastEntry(@Shrinkable @GuardSatisfied TreeMap this) { Entry p = getLastEntry(); + public Map.@Nullable Entry pollLastEntry(@Shrinkable @GuardSatisfied TreeMap this) { + Entry p = getLastEntry(); Map.Entry result = exportEntry(p); if (p != null) deleteEntry(p); diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 463e1b2626c9..7a5118578793 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -227,7 +227,8 @@ public class TreeSet extends AbstractSet */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @PolyModifiable NavigableSet descendingSet(@PolyModifiable TreeSet this) { return new TreeSet<>(m.descendingMap()); + public @PolyModifiable NavigableSet descendingSet(@PolyModifiable TreeSet this) { + return new TreeSet<>(m.descendingMap()); } /** @@ -292,7 +293,8 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied TreeSet this, E e) { return m.put(e, PRESENT)==null; + public boolean add(@Growable @GuardSatisfied TreeSet this, E e) { + return m.put(e, PRESENT)==null; } /** @@ -314,7 +316,8 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied TreeSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o)==PRESENT; + public boolean remove(@Shrinkable @GuardSatisfied TreeSet this, @GuardSatisfied @UnknownSignedness Object o) { + return m.remove(o)==PRESENT; } /** @@ -323,7 +326,8 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied TreeSet this) { m.clear(); + public void clear(@Shrinkable @GuardSatisfied TreeSet this) { + m.clear(); } /** @@ -339,7 +343,8 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection c) { // Use linear-time version if applicable + public boolean addAll(@Growable @GuardSatisfied TreeSet this, Collection c) { + // Use linear-time version if applicable if (m.size()==0 && c.size() > 0 && c instanceof SortedSet && m instanceof TreeMap map) { @@ -505,7 +510,8 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollFirst(@Shrinkable @GuardSatisfied TreeSet this) { Map.Entry e = m.pollFirstEntry(); + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied TreeSet this) { + Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } @@ -514,7 +520,8 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollLast(@Shrinkable @GuardSatisfied TreeSet this) { Map.Entry e = m.pollLastEntry(); + public @Nullable E pollLast(@Shrinkable @GuardSatisfied TreeSet this) { + Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 2c70af8209b6..3c179f7713e5 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -566,7 +566,8 @@ public synchronized E lastElement(@NonEmpty Vector this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void setElementAt(@Replaceable @GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index >= elementCount) { + public synchronized void setElementAt(@Replaceable @GuardSatisfied Vector this, E obj, @NonNegative int index) { + if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } @@ -594,7 +595,8 @@ public synchronized void setElementAt(@Replaceable @GuardSatisfied Vector thi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void removeElementAt(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { if (index >= elementCount) { + public synchronized void removeElementAt(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { + if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } @@ -635,7 +637,8 @@ else if (index < 0) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void insertElementAt(@Growable @GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index > elementCount) { + public synchronized void insertElementAt(@Growable @GuardSatisfied Vector this, E obj, @NonNegative int index) { + if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); } @@ -664,7 +667,8 @@ public synchronized void insertElementAt(@Growable @GuardSatisfied Vector thi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void addElement(@Growable @GuardSatisfied Vector this, E obj) { modCount++; + public synchronized void addElement(@Growable @GuardSatisfied Vector this, E obj) { + modCount++; add(obj, elementData, elementCount); } @@ -685,7 +689,8 @@ public synchronized void insertElementAt(@Growable @GuardSatisfied Vector thi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean removeElement(@Shrinkable @GuardSatisfied @CanShrink Vector this, Object obj) { modCount++; + public synchronized boolean removeElement(@Shrinkable @GuardSatisfied @CanShrink Vector this, Object obj) { + modCount++; int i = indexOf(obj); if (i >= 0) { removeElementAt(i); @@ -702,7 +707,8 @@ public synchronized void insertElementAt(@Growable @GuardSatisfied Vector thi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrink Vector this) { final Object[] es = elementData; + public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrink Vector this) { + final Object[] es = elementData; for (int to = elementCount, i = elementCount = 0; i < to; i++) es[i] = null; modCount++; @@ -822,7 +828,8 @@ public synchronized E get(@GuardSatisfied Vector this, @NonNegative int index */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized E set(@Replaceable @GuardSatisfied Vector this, @NonNegative int index, E element) { if (index >= elementCount) + public synchronized E set(@Replaceable @GuardSatisfied Vector this, @NonNegative int index, E element) { + if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); E oldValue = elementData(index); @@ -853,7 +860,8 @@ private void add(E e, Object[] elementData, int s) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean add(@Growable @GuardSatisfied Vector this, E e) { modCount++; + public synchronized boolean add(@Growable @GuardSatisfied Vector this, E e) { + modCount++; add(e, elementData, elementCount); return true; } @@ -871,7 +879,8 @@ private void add(E e, Object[] elementData, int s) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeElement(o); + public boolean remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return removeElement(o); } /** @@ -887,7 +896,8 @@ private void add(E e, Object[] elementData, int s) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable @GuardSatisfied Vector this, @NonNegative int index, E element) { insertElementAt(element, index); + public void add(@Growable @GuardSatisfied Vector this, @NonNegative int index, E element) { + insertElementAt(element, index); } /** @@ -903,7 +913,8 @@ private void add(E e, Object[] elementData, int s) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized E remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { modCount++; + public synchronized E remove(@Shrinkable @GuardSatisfied @CanShrink Vector this, @NonNegative int index) { + modCount++; if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); E oldValue = elementData(index); @@ -925,7 +936,8 @@ private void add(E e, Object[] elementData, int s) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink Vector this) { removeAllElements(); + public void clear(@Shrinkable @GuardSatisfied @CanShrink Vector this) { + removeAllElements(); } // Bulk Operations @@ -960,7 +972,8 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied Vector this, Collection c) { Object[] a = c.toArray(); + public boolean addAll(@Growable @GuardSatisfied Vector this, Collection c) { + Object[] a = c.toArray(); modCount++; int numNew = a.length; if (numNew == 0) @@ -995,7 +1008,8 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1020,7 +1034,8 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Vector this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -1031,7 +1046,8 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink Vector this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink Vector this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1101,7 +1117,8 @@ private synchronized boolean bulkRemove(Predicate filter) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean addAll(@Growable @GuardSatisfied Vector this, @NonNegative int index, Collection c) { if (index < 0 || index > elementCount) + public synchronized boolean addAll(@Growable @GuardSatisfied Vector this, @NonNegative int index, Collection c) { + if (index < 0 || index > elementCount) throw new ArrayIndexOutOfBoundsException(index); Object[] a = c.toArray(); @@ -1207,7 +1224,8 @@ public synchronized String toString(@GuardSatisfied Vector this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - protected synchronized void removeRange(@Shrinkable @GuardSatisfied @CanShrink Vector this, int fromIndex, int toIndex) { modCount++; + protected synchronized void removeRange(@Shrinkable @GuardSatisfied @CanShrink Vector this, int fromIndex, int toIndex) { + modCount++; shiftTailOverGap(elementData, fromIndex, toIndex); } @@ -1476,7 +1494,8 @@ public synchronized void replaceAll(@Replaceable Vector this, UnaryOperator this, Comparator c) { final int expectedModCount = modCount; + public synchronized void sort(@Replaceable Vector this, Comparator c) { + final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c); if (modCount != expectedModCount) throw new ConcurrentModificationException(); 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 d01d1aefb453..30805f80ef26 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -353,7 +353,8 @@ void removeAt(final int removeIndex) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable ArrayBlockingQueue this, E e) { return super.add(e); + public boolean add(@Growable ArrayBlockingQueue this, E e) { + return super.add(e); } /** @@ -367,7 +368,8 @@ void removeAt(final int removeIndex) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable ArrayBlockingQueue this, E e) { Objects.requireNonNull(e); + public boolean offer(@Growable ArrayBlockingQueue this, E e) { + Objects.requireNonNull(e); final ReentrantLock lock = this.lock; lock.lock(); try { @@ -391,7 +393,8 @@ void removeAt(final int removeIndex) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable ArrayBlockingQueue this, E e) throws InterruptedException { Objects.requireNonNull(e); + public void put(@Growable ArrayBlockingQueue this, E e) throws InterruptedException { + Objects.requireNonNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { @@ -434,7 +437,8 @@ public boolean offer(@Growable ArrayBlockingQueue this, E e, long timeout, Ti // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; + public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { + final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : dequeue(); @@ -445,7 +449,8 @@ public boolean offer(@Growable ArrayBlockingQueue this, E e, long timeout, Ti // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; + public E take(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) @@ -458,7 +463,8 @@ public boolean offer(@Growable ArrayBlockingQueue this, E e, long timeout, Ti // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); + public E poll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { @@ -544,7 +550,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink ArrayBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; + public boolean remove(@Shrinkable @CanShrink ArrayBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); try { @@ -698,7 +705,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; + public void clear(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this) { + final ReentrantLock lock = this.lock; lock.lock(); try { int k; @@ -738,7 +746,8 @@ private static void circularClear(Object[] items, int i, int end) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c) { + return drainTo(c, Integer.MAX_VALUE); } /** @@ -749,7 +758,8 @@ private static void circularClear(Object[] items, int i, int end) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); if (maxElements <= 0) @@ -1521,7 +1531,8 @@ public void forEach(Consumer action) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink ArrayBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink ArrayBlockingQueue this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1530,7 +1541,8 @@ public void forEach(Consumer action) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink ArrayBlockingQueue this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink ArrayBlockingQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1539,7 +1551,8 @@ public void forEach(Consumer action) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ArrayBlockingQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 9627a1ce7e31..2d7d2a4eb368 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -1049,7 +1049,8 @@ public boolean containsValue(@GuardSatisfied @UnknownSignedness Object value) { @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable ConcurrentHashMap this, K key, V value) { return putVal(key, value, false); + public @Nullable V put(@Growable @Replaceable ConcurrentHashMap this, K key, V value) { + return putVal(key, value, false); } /** Implementation for put and putIfAbsent */ @@ -1131,7 +1132,8 @@ else if (f instanceof ReservationNode) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable ConcurrentHashMap this, Map m) { tryPresize(m.size()); + public void putAll(@Growable @Replaceable ConcurrentHashMap this, Map m) { + tryPresize(m.size()); for (Map.Entry e : m.entrySet()) putVal(e.getKey(), e.getValue(), false); } @@ -1147,7 +1149,8 @@ else if (f instanceof ReservationNode) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key) { return replaceNode(key, null, null); + public @Nullable V remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key) { + return replaceNode(key, null, null); } /** @@ -1233,7 +1236,8 @@ else if (f instanceof ReservationNode) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable ConcurrentHashMap this) { long delta = 0L; // negative number of deletions + public void clear(@Shrinkable ConcurrentHashMap this) { + long delta = 0L; // negative number of deletions int i = 0; Node[] tab = table; while (tab != null && i < tab.length) { @@ -1596,7 +1600,8 @@ private void readObject(java.io.ObjectInputStream s) @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V putIfAbsent(@Growable ConcurrentHashMap this, K key, V value) { return putVal(key, value, true); + public @Nullable V putIfAbsent(@Growable ConcurrentHashMap this, K key, V value) { + return putVal(key, value, true); } /** @@ -1606,7 +1611,8 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) + public boolean remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + if (key == null) throw new NullPointerException(); return value != null && replaceNode(key, null, value) != null; } @@ -1618,7 +1624,8 @@ public boolean remove(@Shrinkable ConcurrentHashMap this, @GuardSatisfied @ */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) + public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldValue, V newValue) { + if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); return replaceNode(key, newValue, oldValue) != null; } @@ -1632,7 +1639,8 @@ public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldVal */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V replace(@Replaceable ConcurrentHashMap this, K key, V value) { if (key == null || value == null) + public @Nullable V replace(@Replaceable ConcurrentHashMap this, K key, V value) { + if (key == null || value == null) throw new NullPointerException(); return replaceNode(key, value, null); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 112146f5a7de..5d07aa30b6b7 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -851,7 +851,8 @@ private void initHeadTail(Node h, Node t) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { linkFirst(e); + public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { + linkFirst(e); } /** @@ -865,7 +866,8 @@ private void initHeadTail(Node h, Node t) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable ConcurrentLinkedDeque this, E e) { linkLast(e); + public void addLast(@Growable ConcurrentLinkedDeque this, E e) { + linkLast(e); } /** @@ -877,7 +879,8 @@ private void initHeadTail(Node h, Node t) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { linkFirst(e); + public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { + linkFirst(e); return true; } @@ -892,7 +895,8 @@ private void initHeadTail(Node h, Node t) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable ConcurrentLinkedDeque this, E e) { linkLast(e); + public boolean offerLast(@Growable ConcurrentLinkedDeque this, E e) { + linkLast(e); return true; } @@ -946,7 +950,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { + restart: for (;;) { for (Node first = first(), p = first;;) { final E item; if ((item = p.item) != null) { @@ -968,7 +973,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { + restart: for (;;) { for (Node last = last(), p = last;;) { final E item; if ((item = p.item) != null) { @@ -993,7 +999,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollFirst()); + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { + return screenNullResult(pollFirst()); } /** @@ -1001,7 +1008,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollLast()); + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { + return screenNullResult(pollLast()); } // *** Queue and stack methods *** @@ -1015,7 +1023,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable ConcurrentLinkedDeque this, E e) { return offerLast(e); + public boolean offer(@Growable ConcurrentLinkedDeque this, E e) { + return offerLast(e); } /** @@ -1029,7 +1038,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable ConcurrentLinkedDeque this, E e) { return offerLast(e); + public boolean add(@Growable ConcurrentLinkedDeque this, E e) { + return offerLast(e); } // @SideEffectsOnly("this") @@ -1075,7 +1085,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeFirstOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); + public boolean removeFirstOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { + Objects.requireNonNull(o); for (Node p = first(); p != null; p = succ(p)) { final E item; if ((item = p.item) != null @@ -1102,7 +1113,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeLastOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); + public boolean removeLastOccurrence(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Object o) { + Objects.requireNonNull(o); for (Node p = last(); p != null; p = pred(p)) { final E item; if ((item = p.item) != null @@ -1195,7 +1207,8 @@ public int size() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedDeque this, @GuardSatisfied @UnknownSignedness Object o) { return removeFirstOccurrence(o); + public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedDeque this, @GuardSatisfied @UnknownSignedness Object o) { + return removeFirstOccurrence(o); } /** @@ -1212,7 +1225,8 @@ public int size() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable ConcurrentLinkedDeque this, Collection c) { if (c == this) + public boolean addAll(@Growable ConcurrentLinkedDeque this, Collection c) { + if (c == this) // As historically specified in AbstractQueue#addAll throw new IllegalArgumentException(); @@ -1267,7 +1281,8 @@ else if (p.prev == p) // NEXT_TERMINATOR */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { while (pollFirst() != null) + public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { + while (pollFirst() != null) ; } @@ -1674,7 +1689,8 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1683,7 +1699,8 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedDeque this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1692,7 +1709,8 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedDeque this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index dfc226e3a044..9aef3f354e55 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -307,7 +307,8 @@ boolean casItem(E cmp, E val) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable ConcurrentLinkedQueue this, E e) { return offer(e); + public boolean add(@Growable ConcurrentLinkedQueue this, E e) { + return offer(e); } /** @@ -380,7 +381,8 @@ private Node skipDeadNodes(Node pred, Node c, Node p, Node q) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable ConcurrentLinkedQueue this, E e) { final Node newNode = new Node(Objects.requireNonNull(e)); + public boolean offer(@Growable ConcurrentLinkedQueue this, E e) { + final Node newNode = new Node(Objects.requireNonNull(e)); for (Node t = tail, p = t;;) { Node q = p.next; @@ -410,7 +412,8 @@ else if (p == q) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { restartFromHead: for (;;) { + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { + restartFromHead: for (;;) { for (Node h = head, p = h, q;; p = q) { final E item; if ((item = p.item) != null && p.casItem(item, null)) { @@ -555,7 +558,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedQueue this, @GuardSatisfied @UnknownSignedness Object o) { if (o == null) return false; + public boolean remove(@Shrinkable @CanShrink ConcurrentLinkedQueue this, @GuardSatisfied @UnknownSignedness Object o) { + if (o == null) return false; restartFromHead: for (;;) { for (Node p = head, pred = null; p != null; ) { Node q = p.next; @@ -592,7 +596,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable ConcurrentLinkedQueue this, Collection c) { if (c == this) + public boolean addAll(@Growable ConcurrentLinkedQueue this, Collection c) { + if (c == this) // As historically specified in AbstractQueue#addAll throw new IllegalArgumentException(); @@ -1008,7 +1013,8 @@ public Spliterator spliterator() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1017,7 +1023,8 @@ public Spliterator spliterator() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink ConcurrentLinkedQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1026,13 +1033,15 @@ public Spliterator spliterator() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { bulkRemove(e -> true); + public void clear(@Shrinkable @GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { + bulkRemove(e -> true); } /** diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index fb395ba607d0..2932967cdcb6 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -1374,7 +1374,8 @@ public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultVa */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V put(@Growable @Replaceable ConcurrentSkipListMap this, K key, V value) { if (value == null) + public V put(@Growable @Replaceable ConcurrentSkipListMap this, K key, V value) { + if (value == null) throw new NullPointerException(); return doPut(key, value, false); } @@ -1391,7 +1392,8 @@ public V put(@Growable @Replaceable ConcurrentSkipListMap this, K key, V va */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key) { return doRemove(key, null); + public V remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key) { + return doRemove(key, null); } /** @@ -1447,7 +1449,8 @@ public boolean isEmpty() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable ConcurrentSkipListMap this) { Index h, r, d; Node b; + public void clear(@Shrinkable ConcurrentSkipListMap this) { + Index h, r, d; Node b; VarHandle.acquireFence(); while ((h = head) != null) { if ((r = h.right) != null) // remove indices @@ -1833,7 +1836,8 @@ public boolean equals(@Nullable Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putIfAbsent(@Growable ConcurrentSkipListMap this, K key, V value) { if (value == null) + public V putIfAbsent(@Growable ConcurrentSkipListMap this, K key, V value) { + if (value == null) throw new NullPointerException(); return doPut(key, value, true); } @@ -1847,7 +1851,8 @@ public V putIfAbsent(@Growable ConcurrentSkipListMap this, K key, V value) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) + public boolean remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + if (key == null) throw new NullPointerException(); return value != null && doRemove(key, value) != null; } @@ -1861,7 +1866,8 @@ public boolean remove(@Shrinkable ConcurrentSkipListMap this, @GuardSatisfi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean replace(@Replaceable ConcurrentSkipListMap this, K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) + public boolean replace(@Replaceable ConcurrentSkipListMap this, K key, V oldValue, V newValue) { + if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); for (;;) { Node n; V v; @@ -1887,7 +1893,8 @@ public boolean replace(@Replaceable ConcurrentSkipListMap this, K key, V ol */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V replace(@Replaceable ConcurrentSkipListMap this, K key, V value) { if (key == null || value == null) + public V replace(@Replaceable ConcurrentSkipListMap this, K key, V value) { + if (key == null || value == null) throw new NullPointerException(); for (;;) { Node n; V v; @@ -2163,7 +2170,8 @@ public K higherKey(K key) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public Map.@Unmodifiable Entry pollFirstEntry(@Shrinkable ConcurrentSkipListMap this) { return doRemoveFirstEntry(); + public Map.@Unmodifiable Entry pollFirstEntry(@Shrinkable ConcurrentSkipListMap this) { + return doRemoveFirstEntry(); } /** @@ -2174,7 +2182,8 @@ public K higherKey(K key) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public Map.@Unmodifiable Entry pollLastEntry(@Shrinkable ConcurrentSkipListMap this) { return doRemoveLastEntry(); + public Map.@Unmodifiable Entry pollLastEntry(@Shrinkable ConcurrentSkipListMap this) { + return doRemoveLastEntry(); } /* ---------------- Iterators -------------- */ @@ -2800,13 +2809,15 @@ public V get(Object key) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V put(@Growable @Replaceable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); + public V put(@Growable @Replaceable SubMap this, K key, V value) { + checkKeyBounds(key, m.comparator); return m.put(key, value); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V remove(@Shrinkable SubMap this, Object key) { return (!inBounds(key, m.comparator)) ? null : m.remove(key); + public V remove(@Shrinkable SubMap this, Object key) { + return (!inBounds(key, m.comparator)) ? null : m.remove(key); } @Pure @@ -2846,7 +2857,8 @@ public boolean containsValue(@UnknownSignedness Object value) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable SubMap this) { Comparator cmp = m.comparator; + public void clear(@Shrinkable SubMap this) { + Comparator cmp = m.comparator; for (ConcurrentSkipListMap.Node n = loNode(cmp); isBeforeEnd(n, cmp); n = n.next) { @@ -2859,24 +2871,28 @@ public boolean containsValue(@UnknownSignedness Object value) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putIfAbsent(@Growable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); + public V putIfAbsent(@Growable SubMap this, K key, V value) { + checkKeyBounds(key, m.comparator); return m.putIfAbsent(key, value); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable SubMap this, @UnknownSignedness Object key, @UnknownSignedness Object value) { return inBounds(key, m.comparator) && m.remove(key, value); + public boolean remove(@Shrinkable SubMap this, @UnknownSignedness Object key, @UnknownSignedness Object value) { + return inBounds(key, m.comparator) && m.remove(key, value); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean replace(@Replaceable SubMap this, K key, V oldValue, V newValue) { checkKeyBounds(key, m.comparator); + public boolean replace(@Replaceable SubMap this, K key, V oldValue, V newValue) { + checkKeyBounds(key, m.comparator); return m.replace(key, oldValue, newValue); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V replace(@Replaceable SubMap this, K key, V value) { checkKeyBounds(key, m.comparator); + public V replace(@Replaceable SubMap this, K key, V value) { + checkKeyBounds(key, m.comparator); return m.replace(key, value); } @@ -3039,12 +3055,14 @@ public Map.Entry lastEntry() { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public Map.Entry pollFirstEntry(@Shrinkable SubMap this) { return isDescending ? removeHighest() : removeLowest(); + public Map.Entry pollFirstEntry(@Shrinkable SubMap this) { + return isDescending ? removeHighest() : removeLowest(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public Map.Entry pollLastEntry(@Shrinkable SubMap this) { return isDescending ? removeLowest() : removeHighest(); + public Map.Entry pollLastEntry(@Shrinkable SubMap this) { + return isDescending ? removeLowest() : removeHighest(); } /* ---------------- Submap Views -------------- */ diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 169533365951..ec652df20b05 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -270,7 +270,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable ConcurrentSkipListSet this, E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; + public boolean add(@Growable ConcurrentSkipListSet this, E e) { + return m.putIfAbsent(e, Boolean.TRUE) == null; } /** @@ -289,7 +290,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable ConcurrentSkipListSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o, Boolean.TRUE); + public boolean remove(@Shrinkable ConcurrentSkipListSet this, @GuardSatisfied @UnknownSignedness Object o) { + return m.remove(o, Boolean.TRUE); } /** @@ -297,7 +299,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable ConcurrentSkipListSet this) { m.clear(); + public void clear(@Shrinkable ConcurrentSkipListSet this) { + m.clear(); } /** @@ -366,7 +369,8 @@ public boolean equals(@Nullable Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable ConcurrentSkipListSet this, Collection c) { // Override AbstractSet version to avoid unnecessary call to size() + public boolean removeAll(@Shrinkable ConcurrentSkipListSet this, Collection c) { + // Override AbstractSet version to avoid unnecessary call to size() boolean modified = false; for (Object e : c) if (remove(e)) @@ -414,13 +418,15 @@ public E higher(E e) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollFirst(@Shrinkable ConcurrentSkipListSet this) { Map.Entry e = m.pollFirstEntry(); + public @Nullable E pollFirst(@Shrinkable ConcurrentSkipListSet this) { + Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollLast(@Shrinkable ConcurrentSkipListSet this) { Map.Entry e = m.pollLastEntry(); + public @Nullable E pollLast(@Shrinkable ConcurrentSkipListSet this) { + Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } 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 d61be52e08a3..f0eaf32c0789 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -256,7 +256,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable CopyOnWriteArraySet this) { al.clear(); + public void clear(@Shrinkable CopyOnWriteArraySet this) { + al.clear(); } /** @@ -272,7 +273,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable CopyOnWriteArraySet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return al.remove(o); + public boolean remove(@Shrinkable CopyOnWriteArraySet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return al.remove(o); } /** @@ -290,7 +292,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable CopyOnWriteArraySet this, E e) { return al.addIfAbsent(e); + public boolean add(@Growable CopyOnWriteArraySet this, E e) { + return al.addIfAbsent(e); } /** @@ -361,7 +364,8 @@ private static int compareSets(Object[] snapshot, Set set) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable CopyOnWriteArraySet this, Collection c) { return al.addAllAbsent(c) > 0; + public boolean addAll(@Growable CopyOnWriteArraySet this, Collection c) { + return al.addAllAbsent(c) > 0; } /** @@ -383,7 +387,8 @@ private static int compareSets(Object[] snapshot, Set set) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable CopyOnWriteArraySet this, Collection c) { return al.removeAll(c); + public boolean removeAll(@Shrinkable CopyOnWriteArraySet this, Collection c) { + return al.removeAll(c); } /** @@ -407,7 +412,8 @@ private static int compareSets(Object[] snapshot, Set set) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable CopyOnWriteArraySet this, Collection c) { return al.retainAll(c); + public boolean retainAll(@Shrinkable CopyOnWriteArraySet this, Collection c) { + return al.retainAll(c); } /** @@ -455,7 +461,8 @@ public boolean equals(@Nullable Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable CopyOnWriteArraySet this, Predicate filter) { return al.removeIf(filter); + public boolean removeIf(@Shrinkable CopyOnWriteArraySet this, Predicate filter) { + return al.removeIf(filter); } /** diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 480809be98ff..e02f4ed24a93 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -179,7 +179,8 @@ public class DelayQueue extends AbstractQueue @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable DelayQueue this, E e) { return offer(e); + public boolean add(@Growable DelayQueue this, E e) { + return offer(e); } /** @@ -191,7 +192,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable DelayQueue this, E e) { final ReentrantLock lock = this.lock; + public boolean offer(@Growable DelayQueue this, E e) { + final ReentrantLock lock = this.lock; lock.lock(); try { q.offer(e); @@ -214,7 +216,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable DelayQueue this, E e) { offer(e); + public void put(@Growable DelayQueue this, E e) { + offer(e); } /** @@ -229,7 +232,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable DelayQueue this, E e, long timeout, TimeUnit unit) { return offer(e); + public boolean offer(@Growable DelayQueue this, E e, long timeout, TimeUnit unit) { + return offer(e); } /** @@ -242,7 +246,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { + final ReentrantLock lock = this.lock; lock.lock(); try { E first = q.peek(); @@ -264,7 +269,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; + public E take(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { @@ -310,7 +316,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { @@ -361,7 +368,8 @@ public class DelayQueue extends AbstractQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable DelayQueue this) { return super.remove(); + public E remove(@Shrinkable DelayQueue this) { + return super.remove(); } /** @@ -403,7 +411,8 @@ public int size() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c) { + return drainTo(c, Integer.MAX_VALUE); } /** @@ -414,7 +423,8 @@ public int size() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); if (maxElements <= 0) @@ -445,7 +455,8 @@ public int size() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; + public void clear(@Shrinkable @GuardSatisfied @CanShrink DelayQueue this) { + final ReentrantLock lock = this.lock; lock.lock(); try { q.clear(); @@ -539,7 +550,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink DelayQueue this, @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; + public boolean remove(@Shrinkable @CanShrink DelayQueue this, @UnknownSignedness Object o) { + final ReentrantLock lock = this.lock; lock.lock(); try { return q.remove(o); 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 c2afbc848d3a..f6802807ec18 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -341,7 +341,8 @@ void unlink(@CanShrink LinkedBlockingDeque this, Node x) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable LinkedBlockingDeque this, E e) { if (!offerFirst(e)) + public void addFirst(@Growable LinkedBlockingDeque this, E e) { + if (!offerFirst(e)) throw new IllegalStateException("Deque full"); } @@ -351,7 +352,8 @@ public void addFirst(@Growable LinkedBlockingDeque this, E e) { if (!o */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!offerLast(e)) + public void addLast(@Growable LinkedBlockingDeque this, E e) { + if (!offerLast(e)) throw new IllegalStateException("Deque full"); } @@ -360,7 +362,8 @@ public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!of */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); + public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { + if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; lock.lock(); @@ -376,7 +379,8 @@ public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!of */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); + public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { + if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; lock.lock(); @@ -393,7 +397,8 @@ public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!of */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putFirst(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); + public void putFirst(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; lock.lock(); @@ -411,7 +416,8 @@ public void addLast(@Growable LinkedBlockingDeque this, E e) { if (!of */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putLast(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); + public void putLast(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; lock.lock(); @@ -476,7 +482,8 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeou */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollFirst(); + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + E x = pollFirst(); if (x == null) throw new NoSuchElementException(); return x; } @@ -486,14 +493,16 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeou */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollLast(); + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + E x = pollLast(); if (x == null) throw new NoSuchElementException(); return x; } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; + public @Nullable E pollFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { + final ReentrantLock lock = this.lock; lock.lock(); try { return unlinkFirst(); @@ -504,7 +513,8 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeou // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; + public @Nullable E pollLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { + final ReentrantLock lock = this.lock; lock.lock(); try { return unlinkLast(); @@ -515,7 +525,8 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeou // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E takeFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; + public E takeFirst(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lock(); try { E x; @@ -529,7 +540,8 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeou // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E takeLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; + public E takeLast(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lock(); try { E x; @@ -623,7 +635,8 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeFirstOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; + public boolean removeFirstOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { + if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); try { @@ -641,7 +654,8 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeLastOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; + public boolean removeLastOccurrence(@Shrinkable @CanShrink LinkedBlockingDeque this, Object o) { + if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); try { @@ -672,7 +686,8 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable LinkedBlockingDeque this, E e) { addLast(e); + public boolean add(@Growable LinkedBlockingDeque this, E e) { + addLast(e); return true; } @@ -681,7 +696,8 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable LinkedBlockingDeque this, E e) { return offerLast(e); + public boolean offer(@Growable LinkedBlockingDeque this, E e) { + return offerLast(e); } /** @@ -690,7 +706,8 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { putLast(e); + public void put(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { + putLast(e); } /** @@ -715,22 +732,26 @@ public boolean offer(@Growable LinkedBlockingDeque this, E e, long timeout, T */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + return removeFirst(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { return pollFirst(); + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { + return pollFirst(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { return takeFirst(); + public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { + return takeFirst(); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { return pollFirst(timeout, unit); + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { + return pollFirst(timeout, unit); } /** @@ -782,7 +803,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c) { + return drainTo(c, Integer.MAX_VALUE); } /** @@ -793,7 +815,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); if (maxElements <= 0) @@ -820,7 +843,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable LinkedBlockingDeque this, E e) { addFirst(e); + public void push(@Growable LinkedBlockingDeque this, E e) { + addFirst(e); } /** @@ -828,7 +852,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); + public E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { + return removeFirst(); } // Collection methods @@ -849,7 +874,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink LinkedBlockingDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); + public boolean remove(@Shrinkable @CanShrink LinkedBlockingDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return removeFirstOccurrence(o); } /** @@ -908,7 +934,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable LinkedBlockingDeque this, Collection c) { if (c == this) + public boolean addAll(@Growable LinkedBlockingDeque this, Collection c) { + if (c == this) // As historically specified in AbstractQueue#addAll throw new IllegalArgumentException(); @@ -1048,7 +1075,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this) { + final ReentrantLock lock = this.lock; lock.lock(); try { for (Node f = first; f != null; ) { @@ -1410,7 +1438,8 @@ void forEachFrom(Consumer action, Node p) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingDeque this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingDeque this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1419,7 +1448,8 @@ void forEachFrom(Consumer action, Node p) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingDeque this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingDeque this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1428,7 +1458,8 @@ void forEachFrom(Consumer action, Node p) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque this, 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 bface22fdff0..89a064279192 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -350,7 +350,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable LinkedBlockingQueue this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); + public void put(@Growable LinkedBlockingQueue this, E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); final int c; final Node node = new Node(e); final ReentrantLock putLock = this.putLock; @@ -429,7 +430,8 @@ public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, T */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable LinkedBlockingQueue this, E e) { if (e == null) throw new NullPointerException(); + public boolean offer(@Growable LinkedBlockingQueue this, E e) { + if (e == null) throw new NullPointerException(); final AtomicInteger count = this.count; if (count.get() == capacity) return false; @@ -454,7 +456,8 @@ public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, T // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) throws InterruptedException { final E x; + public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) throws InterruptedException { + final E x; final int c; final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; @@ -477,7 +480,8 @@ public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, T // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { final E x; + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { + final E x; final int c; long nanos = unit.toNanos(timeout); final AtomicInteger count = this.count; @@ -503,7 +507,8 @@ public boolean offer(@Growable LinkedBlockingQueue this, E e, long timeout, T // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { final AtomicInteger count = this.count; + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { + final AtomicInteger count = this.count; if (count.get() == 0) return null; final E x; @@ -568,7 +573,8 @@ void unlink(Node p, Node pred) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink LinkedBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; + public boolean remove(@Shrinkable @CanShrink LinkedBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o == null) return false; fullyLock(); try { for (Node pred = head, p = pred.next; @@ -702,7 +708,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { fullyLock(); + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this) { + fullyLock(); try { for (Node p, h = head; (p = h.next) != null; h = p) { h.next = h; @@ -725,7 +732,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c) { + return drainTo(c, Integer.MAX_VALUE); } /** @@ -736,7 +744,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); if (maxElements <= 0) @@ -1067,7 +1076,8 @@ void forEachFrom(Consumer action, Node p) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink LinkedBlockingQueue this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1076,7 +1086,8 @@ void forEachFrom(Consumer action, Node p) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingQueue this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink LinkedBlockingQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1085,7 +1096,8 @@ void forEachFrom(Consumer action, Node p) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index b3ab3732b04e..392bdb73c7a7 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -1219,7 +1219,8 @@ else if (s == n) // stale */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); + public void put(@Growable LinkedTransferQueue this, E e) { + xfer(e, true, ASYNC, 0L); } /** @@ -1233,7 +1234,8 @@ else if (s == n) // stale */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable LinkedTransferQueue this, E e, long timeout, TimeUnit unit) { xfer(e, true, ASYNC, 0L); + public boolean offer(@Growable LinkedTransferQueue this, E e, long timeout, TimeUnit unit) { + xfer(e, true, ASYNC, 0L); return true; } @@ -1246,7 +1248,8 @@ else if (s == n) // stale */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); + public boolean offer(@Growable LinkedTransferQueue this, E e) { + xfer(e, true, ASYNC, 0L); return true; } @@ -1261,7 +1264,8 @@ else if (s == n) // stale @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable LinkedTransferQueue this, E e) { xfer(e, true, ASYNC, 0L); + public boolean add(@Growable LinkedTransferQueue this, E e) { + xfer(e, true, ASYNC, 0L); return true; } @@ -1277,7 +1281,8 @@ else if (s == n) // stale */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { return xfer(e, true, NOW, 0L) == null; + public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { + return xfer(e, true, NOW, 0L) == null; } /** @@ -1293,7 +1298,8 @@ else if (s == n) // stale */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { if (xfer(e, true, SYNC, 0L) != null) { + public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { + if (xfer(e, true, SYNC, 0L) != null) { Thread.interrupted(); // failure possible only due to interrupt throw new InterruptedException(); } @@ -1325,7 +1331,8 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { E e = xfer(null, false, SYNC, 0L); + public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { + E e = xfer(null, false, SYNC, 0L); if (e != null) return e; Thread.interrupted(); @@ -1334,7 +1341,8 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = xfer(null, false, TIMED, unit.toNanos(timeout)); + public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { + E e = xfer(null, false, TIMED, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) return e; throw new InterruptedException(); @@ -1342,7 +1350,8 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { return xfer(null, false, NOW, 0L); + public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { + return xfer(null, false, NOW, 0L); } /** @@ -1351,7 +1360,8 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); int n = 0; @@ -1366,7 +1376,8 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); int n = 0; @@ -1471,7 +1482,8 @@ public int getWaitingConsumerCount() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink LinkedTransferQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; + public boolean remove(@Shrinkable @CanShrink LinkedTransferQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + if (o == null) return false; restartFromHead: for (;;) { for (Node p = head, pred = null; p != null; ) { Node q = p.next; @@ -1592,7 +1604,8 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink LinkedTransferQueue this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink LinkedTransferQueue this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1601,7 +1614,8 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink LinkedTransferQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1610,13 +1624,15 @@ private void readObject(java.io.ObjectInputStream s) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { bulkRemove(e -> true); + public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { + bulkRemove(e -> true); } /** 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 dded68bae25b..98511f50070d 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -473,7 +473,8 @@ private void heapify() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable PriorityBlockingQueue this, E e) { return offer(e); + public boolean add(@Growable PriorityBlockingQueue this, E e) { + return offer(e); } /** @@ -489,7 +490,8 @@ private void heapify() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable PriorityBlockingQueue this, E e) { if (e == null) + public boolean offer(@Growable PriorityBlockingQueue this, E e) { + if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); @@ -523,7 +525,8 @@ public boolean offer(@Growable PriorityBlockingQueue this, E e) { if ( */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable PriorityBlockingQueue this, E e) { offer(e); // never need to block + public void put(@Growable PriorityBlockingQueue this, E e) { + offer(e); // never need to block } /** @@ -543,12 +546,14 @@ public boolean offer(@Growable PriorityBlockingQueue this, E e) { if ( */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable PriorityBlockingQueue this, E e, long timeout, TimeUnit unit) { return offer(e); // never need to block + public boolean offer(@Growable PriorityBlockingQueue this, E e, long timeout, TimeUnit unit) { + return offer(e); // never need to block } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { + final ReentrantLock lock = this.lock; lock.lock(); try { return dequeue(); @@ -559,7 +564,8 @@ public boolean offer(@Growable PriorityBlockingQueue this, E e) { if ( // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; + public E take(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); E result; try { @@ -573,7 +579,8 @@ public boolean offer(@Growable PriorityBlockingQueue this, E e) { if ( // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); + public @Nullable E poll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); E result; @@ -681,7 +688,8 @@ private void removeAt(int i) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink PriorityBlockingQueue this, @Nullable @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; + public boolean remove(@Shrinkable @CanShrink PriorityBlockingQueue this, @Nullable @UnknownSignedness Object o) { + final ReentrantLock lock = this.lock; lock.lock(); try { int i = indexOf(o); @@ -748,7 +756,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c) { return drainTo(c, Integer.MAX_VALUE); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c) { + return drainTo(c, Integer.MAX_VALUE); } /** @@ -759,7 +768,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); if (maxElements <= 0) @@ -784,7 +794,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; + public void clear(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this) { + final ReentrantLock lock = this.lock; lock.lock(); try { final Object[] es = queue; @@ -1062,7 +1073,8 @@ public Spliterator spliterator() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink PriorityBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink PriorityBlockingQueue this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1071,7 +1083,8 @@ public Spliterator spliterator() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink PriorityBlockingQueue this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink PriorityBlockingQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1080,7 +1093,8 @@ public Spliterator spliterator() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink PriorityBlockingQueue this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 5926699cda9b..c9871800c108 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -856,7 +856,8 @@ void clean(QNode pred, QNode s) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void put(@Growable SynchronousQueue this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); + public void put(@Growable SynchronousQueue this, E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); if (transferer.transfer(e, false, 0) == null) { Thread.interrupted(); throw new InterruptedException(); @@ -894,7 +895,8 @@ public boolean offer(@Growable SynchronousQueue this, E e, long timeout, Time */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable SynchronousQueue this, E e) { if (e == null) throw new NullPointerException(); + public boolean offer(@Growable SynchronousQueue this, E e) { + if (e == null) throw new NullPointerException(); return transferer.transfer(e, true, 0) != null; } @@ -907,7 +909,8 @@ public boolean offer(@Growable SynchronousQueue this, E e, long timeout, Time */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { E e = transferer.transfer(null, false, 0); + public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { + E e = transferer.transfer(null, false, 0); if (e != null) return e; Thread.interrupted(); @@ -925,7 +928,8 @@ public boolean offer(@Growable SynchronousQueue this, E e, long timeout, Time */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = transferer.transfer(null, true, unit.toNanos(timeout)); + public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { + E e = transferer.transfer(null, true, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) return e; throw new InterruptedException(); @@ -940,7 +944,8 @@ public boolean offer(@Growable SynchronousQueue this, E e, long timeout, Time */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { return transferer.transfer(null, true, 0); + public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { + return transferer.transfer(null, true, 0); } /** @@ -982,7 +987,8 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { } + public void clear(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { + } /** * Always returns {@code false}. @@ -1006,7 +1012,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink SynchronousQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return false; + public boolean remove(@Shrinkable @CanShrink SynchronousQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + return false; } /** @@ -1030,7 +1037,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink SynchronousQueue this, Collection c) { return false; + public boolean removeAll(@Shrinkable @CanShrink SynchronousQueue this, Collection c) { + return false; } /** @@ -1042,7 +1050,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, Collection c) { return false; + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, Collection c) { + return false; } /** @@ -1120,7 +1129,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); int n = 0; @@ -1137,7 +1147,8 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); + public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { + Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); int n = 0; From dcae35fb978ea4d04b935d314418dad9c384a188 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 23 May 2026 21:07:23 -0700 Subject: [PATCH 085/119] Rename modifiability qualifiers --- README.md | 3 ++- checker-qual.jar | Bin 290947 -> 291739 bytes .../checker/index/qual/BottomGrowShrink.java | 2 +- .../checker/index/qual/PolyGrowShrink.java | 2 +- .../{BottomGrow.java => BottomGrowable.java} | 2 +- ...tomReplace.java => BottomReplaceable.java} | 2 +- ...ottomShrink.java => BottomShrinkable.java} | 2 +- .../checker/modifiability/qual/Growable.java | 2 +- .../{MaybeGrow.java => MaybeGrowable.java} | 2 +- .../modifiability/qual/MaybeModifiable.java | 4 +-- ...aybeReplace.java => MaybeReplaceable.java} | 2 +- ...{MaybeShrink.java => MaybeShrinkable.java} | 2 +- .../modifiability/qual/Modifiable.java | 2 +- .../qual/{PolyGrow.java => PolyGrowable.java} | 6 ++--- .../modifiability/qual/PolyModifiable.java | 2 +- ...{PolyReplace.java => PolyReplaceable.java} | 6 ++--- .../{PolyShrink.java => PolyShrinkable.java} | 4 +-- .../modifiability/qual/Replaceable.java | 2 +- .../modifiability/qual/Shrinkable.java | 2 +- .../modifiability/qual/Ungrowable.java | 2 +- .../modifiability/qual/UnmodParam.java | 23 ++++++++++++++++++ .../modifiability/qual/Unmodifiable.java | 2 +- .../modifiability/qual/Unreplaceable.java | 2 +- .../modifiability/qual/Unshrinkable.java | 2 +- 24 files changed, 52 insertions(+), 28 deletions(-) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{BottomGrow.java => BottomGrowable.java} (94%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{BottomReplace.java => BottomReplaceable.java} (94%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{BottomShrink.java => BottomShrinkable.java} (94%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{MaybeGrow.java => MaybeGrowable.java} (96%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{MaybeReplace.java => MaybeReplaceable.java} (96%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{MaybeShrink.java => MaybeShrinkable.java} (96%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{PolyGrow.java => PolyGrowable.java} (83%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{PolyReplace.java => PolyReplaceable.java} (88%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{PolyShrink.java => PolyShrinkable.java} (90%) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java diff --git a/README.md b/README.md index b0e385af83d6..0693ee126f37 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,8 @@ To update that copy, run the command below from this directory: rm -f checker-qual.jar && \ cp -p $CHECKERFRAMEWORK/checker-qual/build/libs/checker-qual-*-sources.jar checker-qual.jar && \ (cd src/java.base/share/classes && rm -rf org/checkerframework && \ - unzip ../../../../checker-qual.jar -x 'META-INF*' -x module-info.java && \ + touch META-INF && \ + unzip ../../../../checker-qual.jar -x module-info.java -x 'META-INF*' && \ rm -f org/checkerframework/checker/signedness/SignednessUtilExtra.java && \ chmod -R u+w org/checkerframework) && \ jar tf checker-qual.jar | grep '\.java$' | sed 's/\/[^/]*\.java/;/' | sed 's/\//./g' | sed 's/^/ exports /' | sort -u diff --git a/checker-qual.jar b/checker-qual.jar index 83bc90c1e12ece18cb4d55b108cd9c11b33fe8ed..1d92bd752d579b6ac33721ace7c901bb49fb78d6 100644 GIT binary patch delta 15772 zcmZ{K2Rzl^|G)db*WP=tkUf%3_Ks|#h(xlJS#m>0Mv6G1l$ER^E3zd?87W1>NKr_( zhWyXHx5VfB`+Gb*-tXu0JkRT#^Lm|q-_hgr*;Dit88;~E4F@t$qlk!T(P@{R1=8py zDARgxaAN7+EinrR<&r&h$}s1!;T91&pUW7KDsb}T?2BMyfrl+?CL-28F%83g^Iw}n zrm~J7a^mx_swjKto#^fw8l&n{dxVHltc!Ma$X}TTv3NP66#8-gn$aDKN9oTms^&7E z>9@Da4aiKnySVE@PDZu7lklVIc!MJBa~6k$vZezEu=hp#uPbABw_FSNto61uaGK(L zqVZ)7J*{K8t6)UgF|sH=Sre@tDe!Ax`rSP_ZJ%7h%E3a|Pxg%T3&_k};%k)HN7k1(y>XB{(XOw1P@;jl-S>CX zMx9w}D$uKTlFUc_(q>Hyl}$_)Q8%9pqi<>okrft@NP9biDzl#2b0gp-b<3IDdkse2 z=<`t~S=4=WUsIMAB}2s)s!KQc*D>b%(HJHoA~Lcnm)toOirx^}L+&s(GHBo;j=}|p z7I=L?(^g%5>xd%vZ~cB5`5C=NUA6HpI*5WTqhrJfifa*I;fYcJtyU-stjkevHz`k- zV3*{}W@hc0be;1XOlhH7Q9Y!snRyD2&?B14p}Pj%M(%h&2zrn%cYgk>^>3yZbbi@j zH2dt*E#3O|E3L1sA16&Fcpu$UR8v_R%@bNiI7j#wBUMTCa(|Vnj1Q5 z+jX(3d3WPx#pv2iS_^$T&M6Zb$@YDhiEYlgZggkKACtJ5ZZE**$6fc)(Zlpf+NpcY z)>n&H7&7_awT_4xc-z`2esx}6TVQc4;i9}X_GMOE@eIxGA~CgD>m0e|UtV9ebFkj! zYxx>`uD9s+rHzd&g}ALK2(vN{9AcCBROL+6^1@$@+bl{X(|7occX{0j&bEVTmpDp2 ziI#TlvtpB;$=oD4a#AV#rr`a}J8RA{&xU>?TR|csBGMu{rqWAk4Bg(IcF{l(^rJA0 zIM0({E#3URU0mJ%KLN2(8khDVJ@8PW$NdD z%V=*dq%eZdg}Q`-J|d%{xCewvDsx zdc0+=siOCPEEK%iM>=SQW#$PH^WzAM*c9y3U{O>mHP>AN>tP&+&-}h~x9!v9iCqzt z(VgKeZ(F71uj!_ppd%f~XzH3E$v!KZ>A_&>>NwikSUt5XyJYt`W=#B|$Kai=xcMA2 zmR9$fv#6aBnCnY_j*CDuLPVqoW8xQZT-p^-G9hgL!a-r>5pcrS3m1(#4m*?)io1z> zh;yEDr=`aAMc;U6i4&YVh|)LeIUt}#)!1iuaDri%hx$3@ta$G7Rl4~0$yV~P)7Omr z)ZR61@abCozV6GH5@Yl5S?!ZM0mCdG8B~!ED*UX1VDb~q83*>dx6FXn9%X=~;mT{Q z35_>3beNwyu~|A^agP7(uBzwUfxTs|2Lt>%_N|Msp5sv{l#@i&&aF;}u7-J5|A4th}~a zp%_Ba5Kl9x^%$)Z#Z#5^=pj+W_##&314EkImB8vwU;XbcPY2slc!B~jy}!RF_t0`B zrIh;rbTUo5ld$-WQ?I_|)!5+2hk?O%n>=pHG2XSE;(uLSXYGKZLMRMQ zxlranA7`V}WOM`w5xRL8MgDK9O1B*F&DNv~pAxtIlIT?fXbo-Xg>FBK<^-4G)b)BQ zTVHm)`>5o}-?RC?>GkUaSq|mr`}a^)sdgw`5%(r5^E>Ztbm#Fa9#w}!Em=eZ!^STu z_7~c)bq=2UA!}qkRYv=b5u4lZ!4diB^*Jqj0pBt%71_v=9&A;kiB$n}e*V(KYsk|2 za!PgKOXG`E-NZj)+as6UkuIx1N#EO#wBqK&KWRQ5&AJPc!K^5$s?zo0&l3=&?T>7_td>IS$m+t<2ut{v8(ZnMQ2J{SEne&E7dFMQmM-a zI|cW>a9u4C*@a!VeJgcu&8Wev)BBXAsl~5@?kTiu!=&qIM=__5c8O(=7bUT0*2}9* z!_@{e9#RX@##%49H|rZ!v{n{ml4fK%SD8kj>kOSx-%#Xcl%dsyxJUvmXViY|_0%@s zH!@VQ^AQxtgKDi3b-j%y6npy7g52qeEGwb1XR+U-zxOk22L9z07z6f7)=~UgI-XBEL>j~QV#l#%0 zXcD*N`&9vhm&vUqd%wt~5Hyl7xC&CF6s$i=2PQBN=}AQiysMUj&2LfzDt;{tZWBiht`DxNsCDh}A2X7-H%+ zx2A6UHu@m&*szafJ~1Zp0aveo?2Nguzp3+v!{gY=*zmc^!t#}DSDorw%bIq}6U-zF zZ}XcEFuYWmLH}yKAtIMmqv`71db5na&URJus^-fTy~DRe+Y{Ob+?)?Yo^1SK@cN0T zP+ZR#vXRw(K5TE~pjZP-owY0WZpXg6%5;k%pC~s6dfeBgbK;t*X1^bLrtI`=iu`G= z2U%3mx9~|g@cj1*7g;dK83@rI%25d((ehJxWe0uOTw_Ap4uxB1@q^`9NcBJ!N=HVk1SZXBv@Tj@a3F_Zw7 zx#r$M3qc)=Jyac=?+Yb|zxH^bv~KEm*!TK#Jz;r;8M+(eZCE?$mBQ^)<|nKf_$O|) z6KH+R}@v0UnY;jt6`Cd5sv}1@0$pTi~)d!gEchll=Pu_9#;wiFw++1#sk< z5dUb?bjiwUG)3*;;XHpV#mC)7eWs?*tyjd76Kd}8UH?~!g>;@Fb72rq!~`Wp@@__tq?PG(`H95zAgxD( zCr`2h4~hy$tLJCOGSoiY$Nn&T{m4@&`{x*ULz0?mSmv``nQc$9SY;EE1U1Vmq8g5t zHbh4Ci=?#)Wvm*~VS`qaNT0nN>=sR1Tgfm^PHoR+u9(Okr_r_`)k-6#K9oB1!X$9Ip<_Cy@^J}aYUJ^smRLtv0+ zL@)8)i;6hvIN7NNs`lVlQT`g6y>+H^AG&qIHIf>%)|FR#e>kt{{*p~_5;hx9{$*|u zz2MB&IS|@W+4X6Z{ph|zZYlm#5gk+wL4?#nS|Q-tq=M|g}{!PqAQ91q?EBhjmp}OCxAC1rsbNpl2nZPpVMK@>M99+3 z*|~}?yr(l^b>L~{Z0f4<&J#*!U~EA8>ghdaK3I|M6=4^v7Cm+O+^b$Qesr-y4qYJz zaPFE`V+iQgO8eFodu__9>*J)2o%1QjZtB@&{}&eWejGBA9-ZxucN8-otpI)iDc%` zu8)VFS{VNlMBmb+rrf2oeoo50XIRatv&Tw9q_k!-?b%RRw*{v)9;mXB_HA|mrSWg~L9*f_@4 zo3l(R-|)oov*(1v^(}JkDdirKP(9%|>Eo8)jd>z%wwRir;xMG5Vrn8PlVXO|D3J6i zJa#7QTJ8}mrGVx@XQd!3N~t%VGmgcR+@r%xi{72yD#^|ir~Erqy=gHbWpU;V1(RY| zFhbGOZo?F|LG7bo`$ki#Wvk--{1pDf%7gj=LfD z_0wS$Z2A5xu@P3EJ;pkny~@Wu)RJ88$R|$lhggI^ZJ*Q;)BWL}{Z1maN+cq&^_b$5 z+{eEq)4Jk*PI9T|_JpY%5wuVJYX8%QWjCd_om_y)V~Uv{5&_Q=T4E2L^lP5xtNq^Q z@OmzPbLTQ7-f~MR97gLf8h3M~l70h2^6xa3oN8g#F2fWvx+d;>^e9Q>544QC?%G%f zReR{S3x^vhOAoyoVF}{@6_Q9rV%%T%b@oBggDDdMX@8@ePg57Jg=)FGm_Lt`?R0Xs zbUVuLFJ(OLxmw#EK!?%xbmMBAP`$@cD%4S8Npszt`HXqEP;tN&YN>#eSffJ{fd6u>93;u+%Nhb1C2#{ zDtwYQqBws%H1pvJwfF18r{-eGhfZb5jb}Uzy)YDvG-dtF=4bdl_!LoY;|*^3=-fo! zOtdpn=U;SkB)~`sfqrkeVQBS7G0ORJ?xAX&x1*cx+{5q@&A{X(c;<22g-Uzg(-ik* zn{3O{t@llE#BMfOZ+LUE)mualT)LJENKc}8uo{eC9^{!fRjIeDM%?W8P=P1ncnf<0 zo^q3YR}HHkBsLmb-IDh*02k!-KAl|A8+qs{^a^xS|F}4Dd8rs(B<3gSWW^aa1eE8o zs$48G=Sg2UT%}Qi=cwes$<1j}G9xJ>w72nz`hF0EcwjZ#;`W%7nssU^)oI%&Uf~*I)71b7)?fbL(j~M3-hE& z*-zN)wA?I3_|F-2-&HlX8~NWVbnHLZikPigT~q!57$}GC&_f#!uvj*`(lSZ>v^vvkS;E9O|X+I zyqQqk>3QZto4zFId4Akh%@Et;yNhr&G(xFmw1m1~%XnFN78T{JG%LC&=RRFn^q`KH zpKM`%=0LkZHrYq_LvD7%ZgBz0l94Orm&8-O7Wd<}+edgQ@~S9ntY3?iPuTu4z3rE% z4G+3x*l+AH`hyg5kMxtCa4a~xeR-_w@Yd;}O_prgdzA*NYnI2bTn3}(P0MTp&afZO z_Y>vWbHr(k>0^1Pg#6_ib*ZpTt(GI2ys@`yWF^n1+qqK@UB+_r@(I=>R2AZdj&z}4 zX7|qBrLBK)KF2D-@|--Ko!B{e`S5h3!omTa_)IWI`#HU}e%OQV@CTO1o9oHD-8QO2 z)y(arQxDUuMrEJcypH{;T-(2U`SC4tqGb&CJqmB{g#JZyb)qGuZRv!%cW z!?;*KL_zOKz{*(<{vrX9Zn<8eT7FP_qPH%<@-k;brZ}{4v|2>D_Q${ExMQ z(^-8bUhCG^- zi60{%5ryFZY>Egs?n;Tj?nWR=5=CBGUd4fhQKKSku+0z*EjBr|+qYeYE_OaF;qqzJ zi!9QcB~c#ME3Lc8;&MtZ?8UHl1^W~+@xN~h?itd%UAJ(zZ>i7y(%p(({k2EKjl%VU zT`F(Y)RsoKdO9Y=v}zlUE6&zv4ew{L;PlzoIL0Y^q2%c8E34BnwzE!4w|0Llo^_m* zHKOlPjFpPET8yN`4ro+f$cXZj>QEj@_;vaFDWpgw_?f%uxK8;8z3G-Wp9T9PQO2Uy z#OW`+`eSF02aw(w->*sf=E_VeQBOd~+12U&?C&R)(dDhuG3Yymf;`v`2SfIUmt-Bh z2gfR+>I0H56j~~)uOFMgWq;-;*A%9qFx-Tx6x0dLS_r^Kk5UtB8AE-11xeE#9Ig9c0IttE@!N>4|O ze$=E7tyISMvqIUx&Hf81n^+~IKolIVqR5mbuSapvn{Zl^X zT#g6v<$X3a$DJSS=TQI8oQ5{*kNpT^#DPhxyhyl#z}oow_#HEM32^bj|9ElTs>k<@ zCRO8%IN5S4Tk#@Fih{V z$t-4DjJkDkad(-B1X`hb!6k^QAX$3u`9!;lxXzC%1H}UjZ>rVFeznTqqNz8&JWQFe zaxG#3d&@6A=E;K1;jbd?3Au$ct?U;jmRC|LibIB|UbPX&Cg_US^CmN}wdGIAR|+X$ zrX_;=>F#}`sJ*%%q@~d2qID#CbgZ3wQ~g!j;+I`A`9rz6Y{P}-FKW>n{DEjnj>_Gh zL1$x78R{OsMd7clgyYobubMH0*=9c$O6TKY!C=o8nf3J_zrRMeQ9wpQZsfo>-|kjQ>IgAJvCZB?9Rx=TyWE$zl_uro@;y25z3o= z_>QnzGgiunNq^|p?do-rZ=+U8)WUKr0}iu^BT5{7G{+YM)UT1)r(o27omAqby}!2M zdF!X3D(`{R>lxoa-K{xre95nKP_V`H-Yf3rVJ9w2hwvMpq?e|C(Y)6!qOFQEa+<7q z=kt7((v-yhZAHZk2bbP2Asj{MH;(_Vrf3OwQ+zcS@7KbfQL%Mu0*wfU9-C}wnvxBV z$xHBF0OCk|V#lV-VR|JK~ zDpFr-zNvUw5}jpkWYa3jpdt{zT2k?YnD(W=??u~^fHH}z6vW@}(YkcZZ|q-2f@ad| zpU2M1pr5MI*Jb#-vtJx(zZz4j{Ni<_s%+B7tEI~(5+fY*N%!sw*!>cFypGl3m3^46 zo|!U3Vvb6->k+5?P_%e0y6w}PZ{oX1mVJ+}#gKDt(j3d;7<<{Kw?2FOQsW-F>D&Fa z=<8-fwwJ1CPj`-3FNZjW2J)26xe@h+?(LYudWYRNxus{Oo4+#6@UBSosl3>4)6fvc zPiw4P-gh5VD2H7A%pZSChIHUitA%@uo}|g@k>_1LYP5N$?zk6~`p11Xni&Ev|zGp~VxmJkNUX93SF4;-Yuc zr!&+PPR}PQbK&$X(8|$7w?DG*QoG-4uf#_!aykLB@qm3^T z^)~m4wvBVQ;bfbk&Z^aDq*oaAv~zYq6QBQN2%la3q&!J2dH!_<(a&X!9-K0KZl&AA>rxr6F3R)B zUc+dud%5;VZ#1*n;B1(BkJLD;3irqSleWjcOD*T@`jULo%CdQleZNuC{=hpoGHa=p z_?TVzA0%CUmOkfE@lJ@Bb!V6wA79^ygkfU%HwxdKffvG0c$An*g3pYdZ!CVmnU$=Q zT4-&vc^xwy9Vg~nD_`5Sw^oGpAY(--yj_%f{EWM{`dHm-7Tun`@^%MB%iE0`18+-L znbc%Bo;x0{mpkwRNgh9^RY_kb@gT$G=I}?0!?~huPtprNwC;(CPaM#25g0PQb1`~< zpnMGXCo|$z3v7dfNrRZ~9onVPO}&;ITD&B1yCc8;NVJNmc2fP(nQzyfVbO zNVYuxm+DQS zuxrAqC%vip_-)ldwtalG(_{`w`zt4;G_UWzmw2U2--xsTY=)yqJXeuwk35Y3;v9Q# zi@%IoS^HQOhp^+Z@4wmag&#MckFz1f-=M`1{(Kw; zwQtax$mQFA-|4~Lx9B|x@f|#I=`DI6vRQ%8s98x3y2vnefaM*U1GNVByhD2+C+hHN zC3Vz5>NA=SOu#fGwgI2{;(IhHkbaNei_|v#C6tlOR(y`(R(kOC4a~tb3UkPJ-~|q& zXk~<`3;*6SidID)cjLw6PpI+YwBV<7RPZ_q|5p&{^Awkw+D`^9kD;YeEud`-R>^tb zFY7ptRzUU)63mUGH4wU&f8Qz64!xuTniJ3us8@J0V*(0)-bl zL`1583x>~vNWHgEDTVv^LK(rl$G^Y$fR;m~$Kbm(P@aVEZ^z;LK2SCZOY!@F*N}XK zRr)@OfA{_f^Co_R?-FTGKT(4BAEEB?G{j=y_b2E()lX0;bUNNZ_|E{C)~8iy8p*(`awx_A)+8@ibZoiC@J_lz-BI z-Jj92$d4a?FbBx_3~Ms-3y;}1Si!FmSSIHeSf=YHp3K{10;}ziynsT{QT}yIL1YxT z`33EXoIr!zFK9WSIRjg3PfP%1IG{<21N?xG8bu8lW??Z&{}={Pq7VDmBq?fpl;3R^ z^v|M|5K)RPBMe~Q99jkWLbb(+0@FEIu`e_`jC`OW2@NLr!6^K3f|p8X$HD;tUl^v}a4>2dtmg4j3MnR&Uk(U-oV zHBo|K;2U&TCGWNbT!|SAXcCYoj9~={yLOZsz3cx{KHY_)1-A!aCD#^UjCutBBLXx+ zD0)yV41Ifa5en*e?-Y=L@ZHSzZBB&u?2f52|a?z6AvPcV%6&O(-g)N2=_^!ZipRKaR@ZkEq z81h7Ii(v#Rt7rw(JUF?Ec18-cwh}17uT``nQlPVqaaw}|ds1&3^LPz*87;$Y4Av0F z?sxm&7M+l0>F(dx*1OHhfzNP=hI zVdX`wa6lG_|A4c~zYnvBh;;rA9{j8l_D6>MR14hPK(ljgeN6=K-t~8A1#Ac=aUU0< zEP)gn!^`#GFJJywfj>kh(UTD$>U?BKA| zFAfBO<}b7$*S{|~h={az*g1ZfAj5snfo~7!{{=ng=Cnl=-z2%W&2icK5zbnBm`V)r1dy{^lu&JaF`1hQH3)`dRdU%pW|qO-*nP=hjbgP_6OT zFnkt7Lesy|mRwsu;Xr}b4ndp;-W=KAUvvnO-1-Ft^WUg@c@m0m+(Zj-ZQYdrPc7%Y z@iP47xf~k9&h_t__P-WKdA*g?o8a2I+4`TB z-v}URZwJ5#ltC>>hnFm`o%*2NosQ-|O|T0Of&5(mP7nX>g$m&W89YnC^#a$#tu5^Tm}H3{XyJ~Q9@j)M zWEG2J_&^FNhAaaE3AJ-u1PyS&U__C)e+)G+ia@b~Zk+Ib{Faa!oQ_4YfpSvlGh<>5 z2l6suTN;Rm!|Wz8%u`!V_Vt)2}TJC&D_SQ zWWf2kXcelhNTJ&P+E$t&BAWwTC}FEwDKKQXg_sLm`i`bSLjTd!z<~_bsAD_BM~dNUXekI!g*Upr~ypVM2w5JF)8F2MTD_<8?!==QAJuywlPO2Fd8UN;7p0($JJ#& zVo`}p6#?>;uyB9}cE|+&DG8=1F?tAB4Nf5mZct-L!BHxVJc6#@#yq2frK&V-F*M*j z9jve|HLP$_+ZL^XRCN&mH4QXj&_e*^-7xO>Jyt3W%wYG7K)<2EXdt8mAd(g%1&nE7 zhO!qpa11ejg;PiYW;*Ep^kD)xONUWFV&4$*8V zaeCP98hY67LwI0^+`>O4fyX$C5%@4e6A28kR_UK`T0Bhy#u+eskmVTyQ~McKA1`E{ z*-_TTIfB4^23Dqp5tcFfb&DYbd`uW+MEx6{$@mI8@C_y?xwe2Kq`;ARINtGA*_dJR zyO#*`=WnooL0SyCvrMq%zX+}4g)&djRG>){LxU)N2bC-sVIau@g=g_VlCWz?XMx7L z@Qgd+{u3ut1m>*Jx!xN%AOR$Q!m7-%z;@&9Nl8I_jGKg&mYEGBgV_E7rX27WMf^TZ zXk$mabG8c{H=uVK9H6tfkZK?DTaS9v|1d2k1=u(tX#N8NI5FDDWh$IZ3Yc=i>G~@tMjA1r z-C_)pB{~A&=D|<{W?tBrr?{ZwJeao8>fEpk`LS#cV( zV3rS#X%k@r;1NO?K>{bVeSsg^t`o)4(%_6RbeB0dq?d6ts|118*oDzVkpdS1j0~vQ z1-+gi10vxQ*hwKwK%EEb^#!2bNESy+18Ny)CQby>l{lJ29%n`h{1kwL^PD09cnU&K zL@E=&5Dti_62OcSLJsx|LGNp;5tu?Dj5=~modAU47$nTC_`Zh4^)(?)a9I>11|oLD zTt0Xp4Tf=`;SY#VM`#IKYb#+`r7~??25I20iBRHbF+@mjiy;B?+6Xo7oJR+QMW8y< zU|U+K2y}g_(KhC=0YU|CeM8d&Vo?k`5@w1^+XFQAL+9W(t3jgB2!|Ptc1NTvaP8m& zH^edIz*P#v1!Q{Rj2`rlrUBt%utshF7V8?wUgW7i0Z8wK4f6;ffGc}p-jAmU;M-o9rze;I z5&~i8aFTpi_ZBG?f5+aG*Mk0G_B| zWD%is0uWJ!ATxsiVpZW>PoGHu{pkn^m{WybA;}^zI%?2LE&Q4o7qFW+Ab6bsHq@ZM z?&c7H?=|R7k9{zs-c172ybl)gJeL5t)L}-){68QUb_D#*g-za$_V*SL1j%_&FscrX zY2Csz83mBorvZunB7!8P5W46Fjcz#W&)E@ z3j5}=Cd`a3$4ekV15C6aVY)@|gE|}`TJcXos|}-Rcy9+m3}`A~)8n@(wH{v zK#X<&2z?#sXSI4f0WQ@c44_;G=1KU+umT!g$h`Z<$blq0)A%P>10soI=zwD54#!nA zZwW*|Vk4~2IX!5ptaYn2RuJ5ba1b)Xsg(oaYR9GV0q0KW3v+#_cKyfD;4Xp0kh}jF zMnG-=!~NmmRxTD0WB|u~Y1bCRPuR1q8NfbU(!E8~0G}=xEK@^hQKtt_XBc4^K&c@d zNUxv%CH5nidjG!Dg9sz&EyMn8Mksq>v%VTZBcBGg(G|vUrp>d33$nX0EceNaooVVw z^ALfd+mA6sd|z)%j^B?_MO^|iCUDye-9Q7D_QRFx^;?|eAR_n<_ml$lCa{%3e*l{) zT&%1{2`RCrFvMpj2;i$JT>oxQ;s6hDGJ~54y92PUU;i<*paRDzf85g0f}azxQTUy% zpc$;a!Sq&|5mNI7xL9HYz*94rYZVVf34OVL8o~Uzf~6yx)7m$K6Uu1NG*1^rYr_oGn#waSn!T>M0b&f88NK zE#L$Ji0&dmNM{9|kh}!ite{z^1-KBOHG>^=W^qTZV=Fj;4^qEM$mL}XJJb3a$hF2C zKvdSjf;GkpiNrrefu9YWNV|UENKv4%3Wt93IzoZJ3Lf zzeN}!EfRm#G{D~p4uFet|A;{++%Q!9M@S!mgO&^43la*T0T+&7_92%v{t$yNfRJpaho%AFWnjMvals8@c;Sc3Rquka zKmy^V9u7#GLXGB8SbI}T93u&6&Cz7ILp~jdvEJeB-?lh`07!zbIlmMcRLzg`` zO#rjUF`yc;boCN8Vm003|PY`lrqKlahvJ zA&mDPFIc@=K%g&XqRGMObT}69F?Gn?QR-mUmWmx*^oFG-UMDbP-thKf^Ckf_+-87A~lCs)&ekMZ_Q_M@7=YKt&Lg7Q`kMM3e?; z0SQ6sKbQ4`@cTZ0pGSA!_r#nzXJ&SG_L?!w5Y@-9=cm%&B3=;*>oQ95&ztq#}AwdkcF$ek(|iMQYs+3`b2(uwTYO{!BRI)`4SmnH3N zW_izAVxV%%$nE6^nNvL`=M9}66lKJSGe%|X59|F(UVoEm-7KXJuX3I}`YH2HH>W&A z^kI?KDSSpJIpNJj_oqkW%&B_fUuhFkb&Den@vVH?C#5tf%=PCYY-;<5On#}y2Sh#j zMhFa@VR|wc!c&kQJ3*kLeO;Nq9_L&*`EBJ_!^B5r zK_Qcm6mboD$<|K=G8`qmj!gWbzf>!6SWGtExXj>md;Wzi;n-Gta^A&go!my8k3W~H zckxL%qk~sY6tlYwBKnf7ih_iLWWs}22fpkrY!H3=4X!x5(Zs6)B3p-J_K;7>}nr!u`AR{~d$R)8 z8tQvwwzjJM?hYZ7w9#u36=BK;BCm@+S1oUz%!-=vrc5kPRija_F26F&>rpTtvB;G2 z)pt&g_K^lb_(7@Wi>sHq>+qTxWXjXxG=?cHDwoc^yWpGHermj(;&qH(-jn+Q_&Y^K z=VzWKECo&r(s^2&Qt*_VDwX@fImNlXI1hh(vN3{LuS${D71&HV8NupEke}P3BY$&m zW*((Qe_?6`=Kixm>E4{z7HLrz#d7C*@9i8R@dXE+Svgzhs?|E^d=%qL8#3TX(X@6e ztG!Xv;e3nqw)oR)^~vq8AJImNG+22sGTpo7TW=WUGZFUmVO+>`LbeF=m~&41>)aHB zSm6{UL2ttkGX#Api_dPsPAx}dcE91OUb`G^@UFO$`in_gI(KKU+K2=1U?^O6StHnwcDF;ynGmc>U!;fRN#;if74Xr;F4i*lzjB= z>(#HCKJ|9ahE|bfq};r`C`rva>kx#kZVh5IyQ9se=k$}Oo<=EL^r{Hsz1p&>$QLEU zeBi!NA59IY$ZJqdr0dC|vsHGQqS~H(%AN<`jA8Q25TH$o`8Vdt$gI7NdI$KHO50(K zFg(k~ux|gylv>Yx;Sw}u+gR$*!hN*I&>5MT^UG3KHa&jw>b4Di1c|r;i<;wPu0`5t zB-5|M-@Qw+1TyH156oAmkgVFY*tZzB= z>P9#7Es~pj5~<|gSB-x7*o%7X(~*zl=iPJmeg3PY7fMI+oNG;&y^2owOohH`ixtR- zD%e;5V(nt(3;AaK<5#Kq=td|`eU#&1!Y)RCAT-38n5J8{wlJ6T483vBqFo-byc=Kh zb#H0#Qe@OjFl#_h(Y;RxEO`QMiu{hC(cB|^r>OkT@8_!0??W@lGHyCC%n#f;bzQ@T zZCX%mrL{_xyd#gjrKJ&XIdUNy{iEU|G4b@;{F{a2?_ zZ$}I@vLmyYUiv!BHb`ml*q9~k1jD0&p&PR!&8lVpfDHZVCcB5POzzd3CZQnJKK@4c z1!FDN+-uyA(Us|&3he=#`5uQ-GpF81Whr@YubFy;3LUa+EEJG=#Qb#k9$`BbKQFiM zr%Ch<9X%j&0ks&85K#-?ffn(b^_fWrbvvyi!U(D0GqaaN z;HZkMV3WG$D!;#vkKppaAoW3`h&M}zkY(#2$)EW(j}{V7|Im8dHJ*LiQ24=G_3^B- zYo1Njl#Mg)>Iryi2mRjo=u&OYRI;XCI!{&$nnSo-hq<5m6-DoFdgkCIg4NICUTb#r zE5{DJJj$MQO!blFb-X2mN%=EEl|qP_oB-nQ85Mnk-%Fy2`s4@c!=xRxa_K_CHR`TA zY^n3?7E~YDP@N`yb~>dwGQL*D<#>kL5Pe)JLAJCluC%=R=OJH3#q*0dv5R)6O^J=}5QaazE>(m`b&waz^~jWlg9 zVwB?qIcabHDbX)7W&C++7<;?PE|-qHGg3qOfIkA9Z9OLvTU6G&IeJ5!yZ4M?oYF9Qy#PHV4r=f;nWH1 zrOzizCgWuvn z6&2A%y5idBLp?RS8>?2+EQPuRN1aqs<~;F_B4QKXXYXapw*4BCoOSf*vvt9T_ZOdP zHo9bGKjmD!SzgsNW#^DIbaDJvPr4knRl0u!e`xK@$j(Ok3A%S1Mg6zE@a9KyiG{3A zNji(pO)~W11s=F#1PEpY679_IENp0APWO}_7x?OLb(0hqS9I_qKpcgJjL%(05=O-xsHEtzoRyXq7Kh{u<#nZhWi!o_@l|9Ye55vh_`tW%E*Fi!Wxn8}g8=)Ui875l^*j z)0v!eI|yH=yHo#yJQbmU?%a4sS#WlYcLC!PVi$Y5@MDa`-s!KSlb*}=F6{SSh4`{wu$gH%&0=l8%f0%JZ1O7K66t?S zD!M6@{aI9f8&>T(Xcof!EgSmK1J4d)_z8;7p4wXq=vvC+>ejn&OMdbZ0(x7;vq<=x6kXCVtO+XYEj zwaEi6cSKubUbcj|?~e?FRqJf^5xh7)NUYlB**Cbx2P2N^7SWXiTGz0K$SVYe?8SJO z_Bz7o!#^STCRee>84pc!JgvSN{lh3=#F-jd(|dp6y@G{#6mD=(J;bj#s$1c80L^j3 zWIg4sR_!2l!_RCyP&RUWb8LXu;FJUQ#1oU- zk~`F&Eu<~@sf;D&5I&!ekY>N!Oa8ks{{Z>QE7>90Dyqb^`3biQW--1yt*dQI`PUOl zvYPIdc-b>`uYCUeo1cyqhD;djOFREW4W`g}Y=*DC(2+jFd|4Ti$j2>ZA})dFR}(EjC&< zZ5Qjqf_r*DK4hB7RmLVimL9%%Wh$tyxa&D3ok%VC+3&8;lYT<6i<}@d$o{5{PtZ4IN_*Av`Walko z^!A1%8)MY)_MgPaTXo5H6U+$-_C@C_13Ei7?@lZqkcnWiS?*_)YmM65mi>h$hpfy+ zvWF|+O?**W_Zj&vd}vNR>EXurxCA@$Yq@s_Z6Z`7OH}WAb|Bm=uTS8Ay<4R`T4Maz zzAa|$Hf3U?Zanu8`7vebY4MZmt7pQ$zf_1&9`(wWLV(94MHI;sR__yeW z<|B75?z-N}trvJXV>PK#<}1O3w{%AR(uJIcMrCihPrT)eVe8D&eUETKF*sJP#u4nr!C6g!|IR~p9uw|Dyjlofr_IY7wF@(+uAL>%PixUqA zjWUI&>xlvP@u6> zB{FAl3;Ci$8A`EcBU0yL&U{;mHe!Glds&RiLUgiuN5MIJEA96Mw1Uy0SUWGdqt5>7 zTnl&#g1O`5z8zLOFvgLrlsbYoWN$=TIL~?I4)v9{EPwJgy8Y@_boMd+&n2{YGC@}= z|M$)Uz4K2`%U$sqFtRWXdck)ttQX^2$Jv3?Be!l;jZykN5`Pg{$&e6``tci* z?9&`mU*;SrVP{Bwo6p2!IGn06=c%a4b2qLqN+&_Wo@w20PxnTLL>9EKEz9H^dfvE3 zqw3E=-S#8S$&-T0;IRPVkinl=ebG_hiyYVYpML$>mFaT3&gq!Qn-~B1_8CUC{JYW`Bw>QLmlch z{(5g0AMKhU94d++$@8_H%ZvGdGw{dQ?QFZPd~^DR+2hBrTEP3{UZdi zkm5v;SxCAvmi~j|hvR_DamUV!18wQ#55DNHEd1h1>{Y~;U6u5lJ;@?HuKoC7d$OIJ zyWw==>%gCC{M_T+d$$jEp{o*yqTygayZK0B0?i1H>hA%Bm6`dt41LA0-NQMl+sG{T zqH65*_>+Gdrqq zPV{39&D3-Szm}WE`Q%-KcDVu~JN2YL*gm<>v=*|?V=UMFIWsHE(q4@#M#onv zYgnhGvvdY%a3ypKWIwBT#LHS;_0{K>15VWgJLTsS5_ZT3i`QwA3OIvqg1-2 zOOf-pkOpnHmx8*)%AU9H9Gaq**rPwt&0RDOpKT;F@udm>xE31*Yi5H!jy4XBh_j!7?j_LUi)2glS{df( zp5NjD?(S!`mN4w{dEwJ;WNzw;3tgYOj@?Nbe!k1X zFo3~Sj{iNE+~eFnhavsrIW!J(zE8tn^ROrUVJ{8s zzSc9kd~aSOZP&XaV$Z;*dAtU$R8BvGX2I^0u<=0)Hi8nLov3!)^&uOxx6eAi-8^Ie zc&*(}qHs>Ura^zX@_N*wbM(ciKNmlVCc7}DrUk_?HXfO3qpSU4PFZVRUJ$5JG&8p+ zEav73dLCnc|Hd_m^ooSM(ouo2TDlMgF1i7c%degGE<2SMus_(zef>~{mhZPnmxh%B zddhVNkAxd|9%YBp@~>q7=Oj=n?7Bb{hsdqg_RM0N-@8tz6nX&Tf8bbC}tOG_Y9Z@V|WPFOk>~jEGmmM zYsJ^Jb6buh@r4XGpBj93x^_w~$)nUWEbWe|Z+k)`lW)w&fw7F@%WcMwno>CDxa;|c zP005j=yp`UtMu!k`LXVG4;2YKMQHvrIqs83IRrUJ-&T*3Qy58+VBy(@CoZyoVQjkN zlcA%$fhFY=vVI-XD{%V_Mu|aaa9_702)=OkBc(bV&--)uX0%kUVPiCsBRrC1__F;D z1$XRIa(Y(H*sOLHiq!C9F8j0QygFE(F9z{`3FnFHxfxWd>o9sp#Qe8q>YI;b>$io+ zMi0%(Jd%n%%GQRT{pq4N>uXhMn*Bh0@%(;+c`s+h1C>M7Q1g&;sm)ZJ44c&<3J`4~ z`TLyJj7&rp_B+#)He81P%>R8)TAdh*gURRKGF2vzVi*W!fxFQYqt8_O{)?D{1$V|8 z-RPKcb-8!nGkv_$Z}fCYB$j^tOp29e=Oc^2gxQJT6P~e0qa`DQ3$Bhls5k|C-)ld7ee4qEro4RUZCxfmVT8O->wZbzB_xsMc(G?DH7Wy0Q4% zA8K|)pC_2KD7zi1GY*i7@;xpY&HtmCQ$;__M>gJUpQB-{!g@}RbPgTe+lR-gB1ThP zh=)#{#6u^HhM$S|4_t!ktZ{ipos(Ryi8-a!*%tcr_fZNT1&(PvWRVvry!I+7kxT1H zs{HuJQpr8D4aJE{<9C-vv<|MO9X|Gi>7L4$^(TbAyfnoO+(OoGv8v~2Qz-pRshjWI z@y1+!BWJ9d(cheV+O=WUo1c5EnCbbSAnwvB74|I8KDTVMOfvnjvV=T!)%NAV%&Q-H z#(V0<%0zw}%$In6**$hQcwRljRv8{URb_vtdr)?L!fLXmu$x|)#;nJgF}Y=Vy!N$_ zrS`pK8rIUcQB&)MZs#T+Es~dBI!-*D&^9IOih#wUK#L_qhGPLMI2;Y!Yk$~ZM|=#4 z+xA*m+!mhr!I^{+fKO5-VqwQ zSFz{A2LXM@Dy8FDDnh&`3AulS{cqjw9iJWK^4DLhS^5-th^5pc<<7KQ`*2uC^_NMZ z=4gzus10dan|Sku3Gf{IWtuc6N@=J}pyug!=S=lKRu`1R8nwiysrt_Pie7%x^Muig zOlIF}R(}pv3Ag*shx+qvG^dsi^WHF(P?C`0UuyrZ;hoP>%)TN_?zMy96L*lR>tqlW zXMHiLiNWr>DY?HnMjJ1F4PNCqAVVTmm03HVKwf9fOy;B@GM_wmlG5nZrMt8IB1&1B zLy2`0az>^1j(4Vf!Y_Rg$uJZC%Ce$kxEf5jI`s7<(;83zD0T3`X5Hz;;LD8%h3<&z z@bA;V`l@lD)0&09PKU8LW00L``}3z`iC(%C)+vAE@L{7&?W8!m|NkqI<lahf=$x_&vy1ZdzQb3>)y2dGJJ_xrDli{|L+1T6Z()PFrjKhapmwk>q^Q zhv1#Wz#$)VwuJ#cAHx@_rRjQr@z^I%c`>2Sivy+&Yfj+1k<;&3FhlN zzIls2{i&&<@05HaxQLD#!8&|`7z zVD-1@prkmHDtgoOo5v1kOYuFjoRO}*m_biaAHauqMK^R1-+#)^t6b`~Jf|4WR=D{B z^jf`Pzg;fvr|j}Y?{$8cTGy^FRfoU)W$TtMiM$JBQkU zMc{bL#Kb8NnqMroxK7)+FR$zl16EE)-*Q#tVGC6uvpuEg%7w}jk-%g<1p_BK>BS4C zdH31HZfl&%WeIPt@ZT5a_}zK%Nb>H24)!wBkMGD`2>EM98D64`KjdC$IVJ54UOV3F zT<==s?eyo#_$Rp)Li4y_b5wY$RX(M}&dciT-fttu)Pf`*W4QgSAF<&QRvr;fbB*YV zVhyt7n<-CAas^2W&g7H$@*TO+=lkGGt~|BlOVbzauj0LDj^9YDJSJDzQCO2GS^6X3 zVXjY$`=v+%SB{{UjOlBuQl9(y`I65&4O(W~4I}4z>sS1=qr|R~*!48_{i%s+v19)E z+slGOV04Kqd5+m~*w9`gJ3jV}WxHAH8M(|!FpICB70771q{o8qR)bwodXN@q$m zuaQDoa40-`Cm3;7mi6E1p)FP`cVg%4^?SO^_QvNXIi!|Iw%6#27o~6{tPw4G07!-t z03i_=CIX(0i}FCZMvzYT=PsIt*L?4+?%!YEZ#4qHTm_UUmb{TK5gE2;dh#IJZ(rlP z2CkA~ymAk#-Un+%YkSdxTC0i^`O-zE&(aT`Wjn2#+wvKS?>nnq$Pg+~o^F~mI%Mgb zEBf;N?b`!24AGZjTlTu?wi`<&MwuK}jOPAfPP$-uq|7m{Tukp#V$sQU{pxIO-T+JA zBRiO1$z@(B2v$<5d4cxSSn ze?7BXX;dM?{j?|3!Rwj<$}CgKew6LI`>j8uRYu@}9|5z==QmR9m4^%ZHMz5~I!H$4 zVeO=+;{LL?zgFcBFE!?L(>-|Q^~<80F6NWO`rPeO)swWAnl!P)@1CnfxwiE+jCfe2 z)_ZY>hmy^cJ%8v`A*;VHzB}8aF*`1* zp2fhwNU7>sEQc!QR_TEnTw?MWcub?DN6Vr-YW$Q^9Y` z8-H#^9tM29Sa&3{Y{TW_UaTroSoz;QIpFHU${{H=DVB8-DZMpxAhr)HhRD=Gya!AZ z@0VW_Wnf=Fb`Mhb4&IBW(7mT7>d~i!f20SU{a8xG>myMBx(2Z1fPDZfjg&QQ5-Bvz zRN%WAj68h+%YktMg#%b`MB>witCOFYQJL=`>=jkp25HyE0`~sI(t|HVa-}^*yHgzS z3}H2qU7he=6=cCYaQ*vcPC}ygUw`5CR;1SV6u0jhV7LpqVE6%Dtad>{DrJ8+C0M9~ zWC$cNBH+po>|vy>4DE*u9AV^ae=j`AG?mjKQS8 z|Mib(9E0k)bD(b=s{%B~p`*wJ6cmhOow06gCVP0S{)IbFfyXHxXp{M>YRktFoNH?{NkUiu?AO)`d zgdU?efIL_vg7&{af&xQ}7E75Dvvr8=23MxA0muL~(StnLLxW)h#?#R9J1xrGo5t!O zdzetLYX+-_46qRaAE?=lp#X_9P*;q7lc52lMCQa+<_$ZB8C;!(#q<0H>!ZoBMLUrL z!+^?Ki86MsEi$fItQx}2v&k@l_*s~s`@EYB3-~h&N9^g{o6K$yFbCUzC9uiRfVXqd z&r_i-jQl(tkPk$*Fe@S$7BE~5W7Mj}QiFSTI9f~%=$pryV-O&_fVIIG5ierk$pSQW zmm-?-0=nN=V?1=-PS}P2iPjG^j!ab5<^0=_rF2CG5?SLRU`gD2F%o9S-3WT$N|qmb++lU z9Y9?|T{6;*Ph&va2gkUK^cq}xOhL{X){blQ!#S3OM01;+l{2u!;N&UX!rYG#zomoRPAn_%f*)v+ zeJ&d!P_m8{;oAI83q9y<^B{)bP)n1<@pEl{1cX}K`y%6xYGvc7fUXaYg=_Q66I9jO z=1~6dhANI2(nhyAH@|j3-R%WX0u~sY71zH5^8cF`XD>7_@HC17t1Z?q5tR?5>Da`-)JqpfZan@Yk z|D6>4k2A-ks55wOKnG-SI59-`ILaj8a6DX_Z>|4hSQP>o$Z!h8cUW$&&6g&qw!K)_ zLQysN4#ms0x%Y-@+eh@{Fru0b*XGXee;g%-gGe%*KN5I`7~U>GPmYsAp8W;A@o=aT zCm2XOyKNC6i9oeC6q?V%HQu2YYQ4U+O-mMjJ0<$u&{Czq=^*bP7QgG0cI$1R>;i8RRr|X;7HM~o}+>;)Nc^Qf9aq+Sj0{$7;R4WcA6FJr-s4Q z-P%ImrN${Ead);bG&HcmJ^5Rh9S`8sp@#|ve1itIHt=v$ri;9P1PbY3(`K~LGyP*C zkVGRZp@q6mf0=b!oIaBFlqgmOXX#*Yr%Q;y7bz+uUKKzUJ&qhW&_fAn^(Lc&NYoR7 zB)IYcLk7edpt$DkCc}U})bBIEmYUzAbWQ^d)}Iju%gzYtvyCWi(E@7$X)#2w6=hyC z!k)kTi~48#V`UjCTOzp z0PQ8i(IN@GppYG=rh%yVc?0}SjS>rtjJJ;{mIMSAoCZQWh=QpBI5w78aI%R1D9UI| zz%7CgD|A6VjxsWAaOvrpg#FoL3L6||h0g3JHf7pK=_Cqr*l^ki%M=Re*>S2!_B09t zXQ4H83a1J?v=;tFqfGwi+8_06tl+!t2?t2!A_kPIGAEKfJ z_`m^Mh+9FQe|r&x49Igr)24q6HHhKFi6U&Pn>y5>mlK9^W_^>{3B(*>D2KUVD1I2A zEr8<%*<852NDmeT>s)a3bdsU~HbVu1xZxnZMNVWyK|42Wb9@6x0T~_$lqrZ3DGIANbMquG(b8(tVPUj6!-`ta1S{I7c@uVZ7tUe5EV|r-$!W) z;AFsr0L=OoQ6eV|>;!RI$XN*@fGHD#$zb(`XOUNBwt0Y?>i-n>A+^#d$QObgA;_V? zLJ?sB8T_!@D#9?pB?XjzuMATMT47ALi1Z&Nl>R9UbDXP!0!I;?JW{>~1&=h59pJSH zT>QG!HW?P6B?=Rgr9ou)ftDCtA<~J=kADmeV6VW^fwx-Q0+-j^G||Thf|sJO|3Uh2 zcvgtP%w_4IQhITm5yGIq2^hf@aaa;6!+%V=1g!Hf<4teWz*7QdF2!^U(;)#DlDqo> zgCx!x`MGfw1vOIttyCAGB6m*n?6y6=cz7lhH+%Y&QWd zP?v_0P&)uV8Mvg}kcQS)8$b$-&A>Llws4 za0-agAru(P!>Z;TMnRw_O!;GZ*cQeEWg5K@YG8i^j+X`RZO+_0Q3WXwH0R8^qcJVj_V>4(xIiZB@c02CN1!P@o( zqTta{7}>@fb*&OKa0w>T;y~g!3~z(}dSY96ddG?R8K>p)<18${~h@JQnww1+gh(AGI0 z1>Qukd=JbR;CR3bUD&wteH2(2;C29NJ; z7s%EF3foP&3u0SFG*kpql?W@~+y{FhTCvG6fcSlI^%SfkGD={r2H8o}LH8r+)^IzL zRt=I&;1c9z1TDXB04d@z2|Z{vf}>ERhA4*XgfSd(&b26ztcTCRjRTk$Z?>gJpng+< z0<6A)<8s{?y5)a^(heptGZk-%;0R**o_Li5Vy4jZj*mnj3%VMi&Bm#SZSywIFB?!7 z%cih9u1zSwo53vVwxU3$6%H!yHndH8FkuFxSN@F3D83-@oRPQ?*zSk)a2rbJ?8m8L zc7WjhFg1+k(6MDFQLqc(yWqkRY7Rrs{Kqh%rTAeEJ^b8CD_X!FeEg1@Ua`O#AagyN zewYB2C9FPQKd}Nl;D{w0=$?PU3rlGD^dF!Dd{!`unjusdis|5y91Oj{_HW7P`8HoA z=}9KFrAEL@E1Ve;2(Q+#hl-MeH`Nia>e-p##q;pt}<`I1Wq_ z;In}{hoGNuf!kQj#~_O+PZEt30o^owUYi}*SXq*6aO%K*1{Qwf0p4-|>QzpmdeA8u z$oK_wwjs-y-BvoXnJrqGwlEo8zqT;UcJO6QZf*-h{~NBN@pdr!;CVC?XE9hZ&_!g5 z{xMW&J#_40B!9Nj)XNAwgR_T=kk;a+Jr#g7BUrYFPBQ*%p)DNXpp0DE!kDeYo>V(P z#p<<9nvb{}6+`eCfN_Jfa+f`h5fB{V_;bXfOtT}-f_Uh-A%=h%m^tATFfoA72|hbD z>97=F!5(g=-Z{Z|k5Z$0LC$bYa5%$t z1vW0bYm;FFtGlr~(W9R*fo-h}@@>(2B7mhumxw`E*vdQpEizF&9QJ1giOeo=9uK=w zwE+atf~JdXbBhroD&i3pG2&G)T@uR(uDd}aa=8rxG%3IiZ45jzci7ZR1(Y^)$H`;T z0G~Tf2pm*}2gw^MuZSu;G*A`NL-2LJPz%U< z54G83Simk1=ts$6lc5KX{cxNh(*yeX=(vTR@_^Ik)IpTd#bddEzb7>~7*_ zOAHA*fil;9V4@UGqG0tDmJM+FLa}K$%J}=j0sP}M3LX>S(6ajl|M}$$yTNr9rH9Tz zt1HATIr%}_D+;AE{cwhee>4iH{o(KvxkN01H^LB0yo!MD@$mn1!1RhC2NKcZ@Ft@S z+*yx+(xBK^ksBh&783gwJ%TK-g8&tDB52g3CZbLnb_aqz!^jPiCPEJ_v5$ zV{%dOHVD>k5pFGru0(?2?(GY}1j9_`+`}@18^O@d{5~rE84TOVc!&bCqwv)+A38Vc2{(s3*c(_IK{{TIiUn&3q diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java index 2b3596199228..2c2dc9cc7349 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java @@ -18,4 +18,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({GrowOnly.class, UncheckedCanShrink.class}) -public @interface BottomGrowShrink {} +public @interface BottomGrowableShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java index 6bb99e1af4fc..a6786d44a216 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java @@ -19,4 +19,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @PolymorphicQualifier(UnshrinkableRef.class) -public @interface PolyGrowShrink {} +public @interface PolyGrowableShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrowable.java similarity index 94% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrowable.java index a01b989a8664..74583859f068 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrow.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomGrowable.java @@ -18,4 +18,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({Growable.class, Ungrowable.class}) -public @interface BottomGrow {} +public @interface BottomGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplaceable.java similarity index 94% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplaceable.java index a2609e3558de..13bcf09aa392 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplace.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomReplaceable.java @@ -18,4 +18,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({Replaceable.class, Unreplaceable.class}) -public @interface BottomReplace {} +public @interface BottomReplaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrinkable.java similarity index 94% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrinkable.java index 3cf5d6902f6e..b27c14d30ad7 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomShrinkable.java @@ -18,4 +18,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({Shrinkable.class, Unshrinkable.class}) -public @interface BottomShrink {} +public @interface BottomShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java index 2c8041469c75..4167df7d64b9 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeGrow.class) +@SubtypeOf(MaybeGrowable.class) public @interface Growable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrow.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java index 92789632cc75..628c95dc13c7 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrow.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java @@ -21,4 +21,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface MaybeGrow {} +public @interface MaybeGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java index 5a9a53e8f45c..a36b2a03aa74 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java @@ -7,12 +7,12 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @MaybeGrow @MaybeShrink @MaybeReplace}. Represents an unknown or + * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. Represents an unknown or * arbitrary modifiability capability; the checker cannot determine whether the collection is * growable, shrinkable, or replaceable. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @MaybeGrow @MaybeShrink @MaybeReplace} on each annotated type. + * {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated type. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplace.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java index 70fbbb939007..641d51b83b56 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplace.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java @@ -22,4 +22,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface MaybeReplace {} +public @interface MaybeReplaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java similarity index 96% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrink.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java index d5edc2ccf523..b6889579408b 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java @@ -22,4 +22,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface MaybeShrink {} +public @interface MaybeShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java index 2d5f571deb64..f02de1c0592c 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -13,7 +13,7 @@ * *

As an exception, {@code @Modifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Modifiable Iterator} means - * {@code @MaybeGrow @Shrinkable @MaybeReplace Iterator}. + * {@code @MaybeGrowable @Shrinkable @MaybeReplaceable Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrowable.java similarity index 83% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrowable.java index ef00276e8d64..fe6467671535 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrow.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyGrowable.java @@ -11,7 +11,7 @@ * A polymorphic qualifier for the Grow hierarchy. * *

When used on a method, the Grow capability of the return type matches the Grow capability of - * the argument or receiver annotated with {@code @PolyGrow}. + * the argument or receiver annotated with {@code @PolyGrowable}. * * @checker_framework.manual #modifiability-checker Modifiability Checker * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@PolymorphicQualifier(MaybeGrow.class) -public @interface PolyGrow {} +@PolymorphicQualifier(MaybeGrowable.class) +public @interface PolyGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 87345ae94317..3e8ff27cdef4 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -4,7 +4,7 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @PolyGrow @PolyReplace @PolyShrink}. A polymorphic qualifier for + * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkable}. A polymorphic qualifier for * all three modifiability hierarchies. * *

You should write {@code @PolyModifiable} on methods that preserve or transfer modifiability, diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplaceable.java similarity index 88% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplaceable.java index f8664f330bca..b9f7b0fa5815 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplace.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyReplaceable.java @@ -11,7 +11,7 @@ * A polymorphic qualifier for the Replace hierarchy. * *

When used on a method, the Replace capability of the return type matches the Replace - * capability of the argument or receiver annotated with {@code @PolyReplace}. + * capability of the argument or receiver annotated with {@code @PolyReplaceable}. * * @checker_framework.manual #modifiability-checker Modifiability Checker * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@PolymorphicQualifier(MaybeReplace.class) -public @interface PolyReplace {} +@PolymorphicQualifier(MaybeReplaceable.class) +public @interface PolyReplaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java similarity index 90% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java index f35eece7403b..9ed1fef83e6b 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@PolymorphicQualifier(MaybeShrink.class) -public @interface PolyShrink {} +@PolymorphicQualifier(MaybeShrinkable.class) +public @interface PolyShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java index 2d7c2e7c6926..9759df8a08b4 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeReplace.class) +@SubtypeOf(MaybeReplaceable.class) public @interface Replaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java index 1d7fddbeea03..10af526c558c 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeShrink.class) +@SubtypeOf(MaybeShrinkable.class) public @interface Shrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java index d160c345b0e4..fba98d025e2f 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Ungrowable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeGrow.class) +@SubtypeOf(MaybeGrowable.class) public @interface Ungrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java new file mode 100644 index 000000000000..7342219e5daf --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. This is a syntactic + * sugar for {@link MaybeModifiable}. It is intended to be used on parameters of methods that are + * not designed to change the parameter. This annotation is only allowed to be written within method + * or constructor parameter types, or explicit receiver parameter types. + * + *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to + * {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated type. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +public @interface UnmodParam {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index 53ea1e4066ff..2e233b798c11 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -13,7 +13,7 @@ * *

As an exception, {@code @Unmodifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Unmodifiable Iterator} means - * {@code @MaybeGrow @Unshrinkable @MaybeReplace Iterator}. + * {@code @MaybeGrowable @Unshrinkable @MaybeReplaceable Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java index 32dc1f2e6a47..eec0205d2c50 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unreplaceable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeReplace.class) +@SubtypeOf(MaybeReplaceable.class) public @interface Unreplaceable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java index 347db2a2b656..c52ce9679d8a 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java @@ -18,5 +18,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeShrink.class) +@SubtypeOf(MaybeShrinkable.class) public @interface Unshrinkable {} From 7ff341710f4f250963ba0329f0cf463ce6ec559d Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sat, 23 May 2026 21:17:47 -0700 Subject: [PATCH 086/119] Formatting fixes --- .../classes/java/util/AbstractCollection.java | 19 ++++--- .../share/classes/java/util/AbstractList.java | 21 +++++--- .../share/classes/java/util/AbstractMap.java | 20 ++++--- .../classes/java/util/AbstractQueue.java | 12 +++-- .../share/classes/java/util/AbstractSet.java | 3 +- .../share/classes/java/util/Collection.java | 3 +- .../share/classes/java/util/Collections.java | 26 ++++----- .../share/classes/java/util/EnumMap.java | 8 +-- .../share/classes/java/util/HashMap.java | 8 +-- .../share/classes/java/util/Hashtable.java | 32 ++++++----- .../classes/java/util/IdentityHashMap.java | 20 ++++--- .../share/classes/java/util/Iterator.java | 3 +- .../classes/java/util/LinkedHashMap.java | 20 +++---- .../share/classes/java/util/Map.java | 20 ++++--- .../share/classes/java/util/NavigableMap.java | 6 +-- .../share/classes/java/util/Properties.java | 8 +-- .../java/util/ReverseOrderSortedMapView.java | 10 ++-- .../java/util/SequencedCollection.java | 12 +++-- .../share/classes/java/util/SequencedMap.java | 23 +++++--- .../share/classes/java/util/SortedMap.java | 8 +-- .../share/classes/java/util/Stack.java | 6 ++- .../share/classes/java/util/TreeMap.java | 22 ++++---- .../share/classes/java/util/WeakHashMap.java | 20 ++++--- .../util/concurrent/ConcurrentHashMap.java | 8 +-- .../concurrent/ConcurrentNavigableMap.java | 8 +-- .../concurrent/ConcurrentSkipListMap.java | 20 +++---- .../util/concurrent/CopyOnWriteArrayList.java | 54 ++++++++++++------- .../modifiability/qual/PolyModifiable.java | 2 +- .../modifiability/qual/PolyShrinkable.java | 2 +- 29 files changed, 250 insertions(+), 174 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 0d56b52d7d67..5d38e71d5ab5 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -105,6 +105,7 @@ protected AbstractCollection() { */ @SideEffectFree public abstract @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractCollection this); + @Pure public abstract @NonNegative int size(@GuardSatisfied AbstractCollection this); @@ -283,7 +284,8 @@ private static T[] finishToArray(T[] r, Iterator it) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); + public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { + throw new UnsupportedOperationException(); } /** @@ -305,7 +307,8 @@ private static T[] finishToArray(T[] r, Iterator it) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); + public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + Iterator it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { @@ -369,7 +372,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Collection c) { boolean modified = false; + public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Collection c) { + boolean modified = false; for (E e : c) if (add(e)) modified = true; @@ -400,7 +404,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); while (it.hasNext()) { @@ -436,7 +441,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); while (it.hasNext()) { @@ -466,7 +472,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); + public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { + Iterator it = iterator(); while (it.hasNext()) { it.next(); it.remove(); diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index 058756423853..ee3a2f87e659 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -142,7 +142,8 @@ protected AbstractList() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { add(size(), e); + public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { + add(size(), e); return true; } @@ -169,7 +170,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); + public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { + throw new UnsupportedOperationException(); } /** @@ -187,7 +189,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); + public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { + throw new UnsupportedOperationException(); } /** @@ -202,7 +205,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); + public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { + throw new UnsupportedOperationException(); } @@ -283,7 +287,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { removeRange(0, size()); + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { + removeRange(0, size()); } /** @@ -308,7 +313,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); + public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { + rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); @@ -654,7 +660,8 @@ public int hashCode(@GuardSatisfied AbstractList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); + protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i this, @GuardSatisfi @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied AbstractMap this, K key, V value) { throw new UnsupportedOperationException(); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied AbstractMap this, K key, V value) { + throw new UnsupportedOperationException(); } /** @@ -277,7 +278,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); + public @Nullable V remove(@Shrinkable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + Iterator> i = entrySet().iterator(); Entry correctEntry = null; if (key==null) { while (correctEntry==null && i.hasNext()) { @@ -323,7 +325,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) + public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this, Map m) { + for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); } @@ -341,7 +344,8 @@ public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { entrySet().clear(); + public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { + entrySet().clear(); } @@ -391,7 +395,7 @@ public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this * method will not all return the same set. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied AbstractMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { @@ -465,7 +469,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied AbstractMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { @@ -523,7 +527,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - public abstract @IteratorPolyMod @PolyShrink @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); + public abstract @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index 67de85968221..518de35e56bd 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -107,7 +107,8 @@ public abstract class AbstractQueue @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { if (offer(e)) + public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { + if (offer(e)) return true; else throw new IllegalStateException("Queue full"); @@ -126,7 +127,8 @@ public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { E x = poll(); + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { + E x = poll(); if (x != null) return x; else @@ -162,7 +164,8 @@ public E element(@GuardSatisfied @NonEmpty AbstractQueue this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) { while (poll() != null) + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) { + while (poll() != null) ; } @@ -197,7 +200,8 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractQueue this, Collection c) { if (c == null) + public boolean addAll(@Growable @GuardSatisfied AbstractQueue this, Collection c) { + if (c == null) throw new NullPointerException(); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index d6a689363555..bc52ec9e9f9e 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -179,7 +179,8 @@ public int hashCode(@GuardSatisfied AbstractSet this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { + Objects.requireNonNull(c); boolean modified = false; if (size() > c.size()) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index cf08a7d6292a..aee783f15f80 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -624,7 +624,8 @@ default T[] toArray(Collection this, IntFunction generator) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); + default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { + Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); while (each.hasNext()) { diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 69e447153637..3e21cc2578b1 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -33,7 +33,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; @@ -3218,7 +3218,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink SynchronizedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable SynchronizedMap this) { synchronized (mutex) { if (keySet==null) keySet = new SynchronizedSet<>(m.keySet(), mutex); @@ -3227,7 +3227,7 @@ public void clear() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { synchronized (mutex) { if (entrySet==null) entrySet = new SynchronizedSet<>(m.entrySet(), mutex); @@ -3235,7 +3235,7 @@ public void clear() { } } - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink SynchronizedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SynchronizedMap this) { synchronized (mutex) { if (values==null) values = new SynchronizedCollection<>(m.values(), mutex); @@ -3544,19 +3544,19 @@ public NavigableMap descendingMap() { } } - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink SynchronizedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SynchronizedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink SynchronizedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink SynchronizedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } @@ -4385,8 +4385,8 @@ private String badValueMsg(Object value) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } - public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink CheckedMap this) { return m.keySet(); } - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink CheckedMap this) { return m.values(); } + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable CheckedMap this) { return m.keySet(); } + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable CheckedMap this) { return m.values(); } @Pure public boolean equals(Object o) { return o == this || m.equals(o); } @Pure @@ -4427,7 +4427,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); return entrySet; @@ -4957,17 +4957,17 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink CheckedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable CheckedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink CheckedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable CheckedNavigableMap this) { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink CheckedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable CheckedNavigableMap this) { return checkedNavigableSet(nm.descendingKeySet(), keyType); } diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index a257ac644259..93bcc3f6da52 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -426,7 +426,7 @@ public void clear(@Shrinkable EnumMap this) { * @return a set view of the keys contained in this enum map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink EnumMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable EnumMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -474,7 +474,7 @@ public void clear(@Shrinkable KeySet this) { * @return a collection view of the values contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink EnumMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable EnumMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -528,7 +528,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 3c8f01e98d41..6226d56444b9 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -962,7 +962,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1102,7 +1102,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1169,7 +1169,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 74b64b742139..04007f5d5075 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -514,7 +514,8 @@ private void addEntry(int hash, K key, V value, int index) { @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized @Nullable V put(@Growable @Replaceable @GuardSatisfied Hashtable this, K key, V value) { // Make sure the value is not null + public synchronized @Nullable V put(@Growable @Replaceable @GuardSatisfied Hashtable this, K key, V value) { + // Make sure the value is not null if (value == null) { throw new NullPointerException(); } @@ -548,7 +549,8 @@ private void addEntry(int hash, K key, V value, int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized @Nullable V remove(@Shrinkable @GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { Entry tab[] = table; + public synchronized @Nullable V remove(@Shrinkable @GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { + Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") @@ -581,7 +583,8 @@ private void addEntry(int hash, K key, V value, int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable this, Map t) { for (Map.Entry e : t.entrySet()) + public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable this, Map t) { + for (Map.Entry e : t.entrySet()) put(e.getKey(), e.getValue()); } @@ -590,7 +593,8 @@ public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) { Entry tab[] = table; + public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) { + Entry tab[] = table; for (int index = tab.length; --index >= 0; ) tab[index] = null; modCount++; @@ -707,7 +711,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); return keySet; @@ -756,7 +760,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); return entrySet; @@ -847,7 +851,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), this); @@ -1006,7 +1010,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized V putIfAbsent(@Growable Hashtable this, K key, V value) { Objects.requireNonNull(value); + public synchronized V putIfAbsent(@Growable Hashtable this, K key, V value) { + Objects.requireNonNull(value); // Makes sure the key is not already in the hashtable. Entry tab[] = table; @@ -1031,7 +1036,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Objects.requireNonNull(value); + public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + Objects.requireNonNull(value); Entry tab[] = table; int hash = key.hashCode(); @@ -1057,7 +1063,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean replace(@Replaceable Hashtable this, K key, V oldValue, V newValue) { Objects.requireNonNull(oldValue); + public synchronized boolean replace(@Replaceable Hashtable this, K key, V oldValue, V newValue) { + Objects.requireNonNull(oldValue); Objects.requireNonNull(newValue); Entry tab[] = table; int hash = key.hashCode(); @@ -1080,7 +1087,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized V replace(@Replaceable Hashtable this, K key, V value) { Objects.requireNonNull(value); + public synchronized V replace(@Replaceable Hashtable this, K key, V value) { + Objects.requireNonNull(value); Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 193d30e3e48e..049baa1d37ad 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -469,7 +469,8 @@ private boolean containsMapping(@UnknownSignedness @GuardSatisfied @Nullable Obj @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, K key, V value) { final Object k = maskNull(key); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, K key, V value) { + final Object k = maskNull(key); retryAfterResize: for (;;) { final Object[] tab = table; @@ -551,7 +552,8 @@ private boolean resize(int newCapacity) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, Map m) { int n = m.size(); + public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, Map m) { + int n = m.size(); if (n == 0) return; if (n > size) @@ -574,7 +576,8 @@ private boolean resize(int newCapacity) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); + public @Nullable V remove(@Shrinkable @GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); @@ -671,7 +674,8 @@ private void closeDeletion(int d) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied IdentityHashMap this) { modCount++; + public void clear(@Shrinkable @GuardSatisfied IdentityHashMap this) { + modCount++; Object[] tab = table; for (int i = 0; i < tab.length; i++) tab[i] = null; @@ -1046,7 +1050,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1166,7 +1170,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1284,7 +1288,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index 798b8538efee..c1dd90bf6868 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -122,7 +122,8 @@ public interface Iterator { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { throw new UnsupportedOperationException("remove"); + default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { + throw new UnsupportedOperationException("remove"); } /** diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index a408dd0b707c..d994b2180f4a 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -662,7 +662,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable LinkedHashMap this) { return sequencedKeySet(); } @@ -675,7 +675,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return {@inheritDoc} * @since 21 */ - public @PolyShrink @Ungrowable SequencedSet sequencedKeySet(@PolyShrink LinkedHashMap this) { + public @PolyShrinkable @Ungrowable SequencedSet sequencedKeySet(@PolyShrinkable LinkedHashMap this) { Set ks = keySet; if (ks == null) { SequencedSet sks = new LinkedKeySet(false); @@ -829,7 +829,7 @@ public SequencedSet reversed() { * @return a view of the values contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable LinkedHashMap this) { return sequencedValues(); } @@ -842,7 +842,7 @@ public SequencedSet reversed() { * @return {@inheritDoc} * @since 21 */ - public @PolyShrink @Ungrowable SequencedCollection sequencedValues(@PolyShrink LinkedHashMap this) { + public @PolyShrinkable @Ungrowable SequencedCollection sequencedValues(@PolyShrinkable LinkedHashMap this) { Collection vs = values; if (vs == null) { SequencedCollection svs = new LinkedValues(false); @@ -950,7 +950,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -963,7 +963,7 @@ public SequencedCollection reversed() { * @return {@inheritDoc} * @since 21 */ - public @PolyShrink @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable LinkedHashMap this) { + public @PolyShrinkable @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable LinkedHashMap this) { Set> es = entrySet; if (es == null) { SequencedSet> ses = new LinkedEntrySet(false); @@ -1269,17 +1269,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink ReversedLinkedHashMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReversedLinkedHashMapView this) { return base.sequencedKeySet().reversed(); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ReversedLinkedHashMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReversedLinkedHashMapView this) { return base.sequencedValues().reversed(); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 90114282fb60..591c8478294b 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -403,7 +403,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -421,7 +421,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable @PolyNonEmpty Collection values(@PolyShrink @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Collection values(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -440,7 +440,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the @@ -908,7 +908,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V value) { V v = get(key); + default @Nullable V putIfAbsent(@Growable Map this, K key, V value) { + V v = get(key); if (v == null) { v = put(key, value); } @@ -953,7 +954,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Object curValue = get(key); + default boolean remove(@Shrinkable Map this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { return false; @@ -1004,7 +1006,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V oldValue, V newValue) { Object curValue = get(key); + default boolean replace(@Replaceable Map this, K key, V oldValue, V newValue) { + Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { return false; @@ -1053,7 +1056,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V value) { V curValue; + default @Nullable V replace(@Replaceable Map this, K key, V value) { + V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); } diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 35c90af29958..51d379b92838 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nullness.qual.KeyFor; @@ -313,7 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink NavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable NavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -330,7 +330,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink NavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable NavigableMap this); /** * Returns a view of the portion of this map whose keys range from diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index a8f088627ccb..0d4b048197c7 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -1412,19 +1412,19 @@ public synchronized String toString() { @Override @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrink Properties this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrinkable Properties this) { return Collections.synchronizedSet(map.keySet(), this); } @Override @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink Properties this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable Properties this) { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable Properties this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Properties this) { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index bda33771dfa0..c7cf58a7393f 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -115,7 +115,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink ReverseOrderSortedMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE @SideEffectFree @@ -130,7 +130,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ReverseOrderSortedMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReverseOrderSortedMapView this) { return new AbstractCollection<>() { // inherit add(), which throws UOE @SideEffectFree @@ -145,7 +145,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE @SideEffectFree @@ -438,7 +438,7 @@ public String toString() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable Submap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Submap this) { return new AbstractSet<>() { @SideEffectFree public Iterator> iterator() { diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index c1f051acea37..8df7e5539589 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -113,7 +113,8 @@ public interface SequencedCollection extends Collection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addFirst(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); + default void addFirst(@Growable SequencedCollection this, E e) { + throw new UnsupportedOperationException(); } /** @@ -132,7 +133,8 @@ public interface SequencedCollection extends Collection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addLast(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); + default void addLast(@Growable SequencedCollection this, E e) { + throw new UnsupportedOperationException(); } /** @@ -186,7 +188,8 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.iterator(); + default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { + var it = this.iterator(); E e = it.next(); it.remove(); return e; @@ -209,7 +212,8 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); + default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { + var it = this.reversed().iterator(); E e = it.next(); it.remove(); return e; diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index a7f861d733f7..a584cc370b09 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -27,7 +27,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -200,7 +200,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { var it = entrySet().iterator(); + default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { + var it = entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); it.remove(); @@ -226,7 +227,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { var it = reversed().entrySet().iterator(); + default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { + var it = reversed().entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); it.remove(); @@ -253,7 +255,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); + default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { + throw new UnsupportedOperationException(); } /** @@ -273,7 +276,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); + default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { + throw new UnsupportedOperationException(); } /** @@ -292,7 +296,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyShrink @Ungrowable SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { + default @PolyShrinkable @Ungrowable SequencedSet sequencedKeySet(@PolyShrinkable SequencedMap this) { + class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { Collection view() { return SequencedMap.this.keySet(); } @@ -328,7 +333,8 @@ public int hashCode() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyShrink @Ungrowable SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { + default @PolyShrinkable @Ungrowable SequencedCollection sequencedValues(@PolyShrinkable SequencedMap this) { + class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { Collection view() { return SequencedMap.this.values(); } @@ -355,7 +361,8 @@ public SequencedCollection reversed() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyShrink @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { class SeqEntrySet extends AbstractMap.ViewCollection> + default @PolyShrinkable @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { + class SeqEntrySet extends AbstractMap.ViewCollection> implements SequencedSet> { Collection> view() { return SequencedMap.this.entrySet(); diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 8c01a694261f..5a7c0460749d 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -265,7 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied SortedMap this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -286,7 +286,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied SortedMap this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -307,7 +307,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** * Throws {@code UnsupportedOperationException}. The encounter order induced by this diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 301b50ae5a0d..ab8c4b91a1da 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -82,7 +82,8 @@ public class Stack extends Vector { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E push(@Growable @GuardSatisfied Stack this, E item) { addElement(item); + public E push(@Growable @GuardSatisfied Stack this, E item) { + addElement(item); return item; } @@ -97,7 +98,8 @@ public class Stack extends Vector { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Stack this) { E obj; + public synchronized E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Stack this) { + E obj; int len = size(); obj = peek(); diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 0a63820cadd0..299209736763 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; @@ -1200,7 +1200,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1208,7 +1208,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } @@ -1217,7 +1217,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1243,7 +1243,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1275,7 +1275,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } @@ -2110,19 +2110,19 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - public final @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink NavigableSubMap this) { + public final @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable NavigableSubMap this) { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } @SideEffectFree - public final @IteratorPolyMod @PolyShrink @Ungrowable Set keySet(@PolyShrink NavigableSubMap this) { + public final @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable NavigableSubMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink NavigableSubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable NavigableSubMap this) { return descendingMap().navigableKeySet(); } @@ -2467,7 +2467,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); } @@ -2561,7 +2561,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); } diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 8ad6b1cf77aa..61ce125e513e 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -494,7 +494,8 @@ Entry getEntry(Object key) { @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied WeakHashMap this, K key, V value) { Object k = maskNull(key); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied WeakHashMap this, K key, V value) { + Object k = maskNull(key); int h = hash(k); Entry[] tab = getTable(); int i = indexFor(h, tab.length); @@ -587,7 +588,8 @@ private void transfer(Entry[] src, Entry[] dest) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this, Map m) { int numKeysToBeAdded = m.size(); + public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this, Map m) { + int numKeysToBeAdded = m.size(); if (numKeysToBeAdded == 0) return; @@ -637,7 +639,8 @@ private void transfer(Entry[] src, Entry[] dest) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); + public @Nullable V remove(@Shrinkable @GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + Object k = maskNull(key); int h = hash(k); Entry[] tab = getTable(); int i = indexFor(h, tab.length); @@ -697,7 +700,8 @@ boolean removeMapping(Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied WeakHashMap this) { // clear out ref queue. We don't need to expunge entries + public void clear(@Shrinkable @GuardSatisfied WeakHashMap this) { + // clear out ref queue. We don't need to expunge entries // since table is getting cleared. while (queue.poll() != null) ; @@ -932,7 +936,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrink @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -995,7 +999,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1048,7 +1052,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 2d7d2a4eb368..549a557f883b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -40,7 +40,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -1287,7 +1287,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrink ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrinkable ConcurrentHashMap this) { KeySetView ks; if ((ks = keySet) != null) return ks; return keySet = new KeySetView(this, null); @@ -1312,7 +1312,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; return values = new ValuesView(this); @@ -1336,7 +1336,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index b6fe3704d308..88089e87c66f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -147,7 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -168,7 +168,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentNavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -187,5 +187,5 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 2932967cdcb6..a8674395be54 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -40,7 +40,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; -import org.checkerframework.checker.modifiability.qual.PolyShrink; +import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; @@ -1656,14 +1656,14 @@ else if (doRemove(key, v) != null) * @return a navigable set view of the keys in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); @@ -1689,7 +1689,7 @@ else if (doRemove(key, v) != null) * weakly consistent. */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; return values = new Values<>(this); @@ -1723,7 +1723,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1738,7 +1738,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet descendingKeySet(@PolyShrink ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3068,28 +3068,28 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet keySet(@PolyShrink SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable NavigableSet navigableKeySet(@PolyShrink SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Collection values(@PolyShrink SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SubMap this) { Values vs; if ((vs = valuesView) != null) return vs; return valuesView = new Values<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrink @Ungrowable Set> entrySet(@PolyShrink SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable SubMap this) { EntrySet es; if ((es = entrySetView) != null) return es; return entrySetView = new EntrySet(this); 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 79b0c90ebf95..0679f8f9ad49 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -485,7 +485,8 @@ public E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { + public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { + synchronized (lock) { Object[] es = getArray(); E oldValue = elementAt(es, index); @@ -508,7 +509,8 @@ public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { + public boolean add(@Growable CopyOnWriteArrayList this, E e) { + synchronized (lock) { Object[] es = getArray(); int len = es.length; es = Arrays.copyOf(es, len + 1); @@ -527,7 +529,8 @@ public boolean add(@Growable CopyOnWriteArrayList this, E e) { synchro */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { + public void add(@Growable CopyOnWriteArrayList this, int index, E element) { + synchronized (lock) { Object[] es = getArray(); int len = es.length; if (index > len || index < 0) @@ -554,7 +557,8 @@ public void add(@Growable CopyOnWriteArrayList this, int index, E element) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable CopyOnWriteArrayList this, E e) { add(0, e); + public void addFirst(@Growable CopyOnWriteArrayList this, E e) { + add(0, e); } /** @@ -564,7 +568,8 @@ public void add(@Growable CopyOnWriteArrayList this, int index, E element) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { + public void addLast(@Growable CopyOnWriteArrayList this, E e) { + synchronized (lock) { add(getArray().length, e); } } @@ -578,7 +583,8 @@ public void addLast(@Growable CopyOnWriteArrayList this, E e) { synchr */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { synchronized (lock) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { + synchronized (lock) { Object[] es = getArray(); int len = es.length; E oldValue = elementAt(es, index); @@ -605,7 +611,8 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList t */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { + synchronized (lock) { if (getArray().length == 0) throw new NoSuchElementException(); else @@ -621,7 +628,8 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWrit */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { + synchronized (lock) { int size = getArray().length; if (size == 0) throw new NoSuchElementException(); @@ -644,7 +652,8 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWrite */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] snapshot = getArray(); + public boolean remove(@Shrinkable @CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + Object[] snapshot = getArray(); int index = indexOfRange(o, snapshot, 0, snapshot.length); return index >= 0 && remove(o, snapshot, index); } @@ -725,7 +734,8 @@ void removeRange(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int fr */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addIfAbsent(@Growable CopyOnWriteArrayList this, E e) { Object[] snapshot = getArray(); + public boolean addIfAbsent(@Growable CopyOnWriteArrayList this, E e) { + Object[] snapshot = getArray(); return indexOfRange(e, snapshot, 0, snapshot.length) < 0 && addIfAbsent(e, snapshot); } @@ -794,7 +804,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -816,7 +827,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -833,7 +845,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = c.toArray(); + public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection c) { + Object[] cs = c.toArray(); if (c.getClass() != ArrayList.class) { cs = cs.clone(); } @@ -865,7 +878,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this) { + synchronized (lock) { setArray(new Object[0]); } } @@ -882,7 +896,8 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? + public boolean addAll(@Growable CopyOnWriteArrayList this, Collection c) { + Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? ((CopyOnWriteArrayList)c).getArray() : c.toArray(); if (cs.length == 0) return false; @@ -920,7 +935,8 @@ public boolean addAll(@Growable CopyOnWriteArrayList this, Collection this, int index, Collection c) { Object[] cs = c.toArray(); + public boolean addAll(@Growable CopyOnWriteArrayList this, int index, Collection c) { + Object[] cs = c.toArray(); synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -961,7 +977,8 @@ public void forEach(Consumer action) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink CopyOnWriteArrayList this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink CopyOnWriteArrayList this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1035,7 +1052,8 @@ void replaceAllRange(UnaryOperator operator, int i, int end) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void sort(@Replaceable CopyOnWriteArrayList this, Comparator c) { synchronized (lock) { + public void sort(@Replaceable CopyOnWriteArrayList this, Comparator c) { + synchronized (lock) { sortRange(c, 0, getArray().length); } } diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 3e8ff27cdef4..93c85ea6db3d 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -4,7 +4,7 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkable}. A polymorphic qualifier for + * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkableable}. A polymorphic qualifier for * all three modifiability hierarchies. * *

You should write {@code @PolyModifiable} on methods that preserve or transfer modifiability, diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java index 9ed1fef83e6b..252d128e9ed7 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java @@ -19,4 +19,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @PolymorphicQualifier(MaybeShrinkable.class) -public @interface PolyShrinkable {} +public @interface PolyShrinkableable {} From b62a2abd98c61a922944ca1dd9a94f84aabf2509 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sun, 24 May 2026 20:09:43 -0700 Subject: [PATCH 087/119] Use `ci-org-and-branch` instead of `ci-info` --- .azure/azure-pipelines.yml | 4 ++-- .azure/azure-pipelines.yml.m4 | 4 ++-- .github/workflows/ci.yml | 6 +++--- .github/workflows/ci.yml.m4 | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index d0a6278a2556..6c1a142eb0ed 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -79,7 +79,7 @@ jobs: - bash: | git config --global --add safe.directory $(cd ../jdk21u && pwd) cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) + eval $(/tmp/$USER/plume-scripts/ci-org-and-branch typetools) set echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" displayName: git merge plan @@ -92,7 +92,7 @@ jobs: git config --global core.longpaths true git config --global core.protectNTFS false cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) + eval $(/tmp/$USER/plume-scripts/ci-org-and-branch typetools) set echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) diff --git a/.azure/azure-pipelines.yml.m4 b/.azure/azure-pipelines.yml.m4 index 5e1d4c8e38af..fb878ceafc54 100644 --- a/.azure/azure-pipelines.yml.m4 +++ b/.azure/azure-pipelines.yml.m4 @@ -82,7 +82,7 @@ jobs: - bash: | git config --global --add safe.directory $(cd ../jdk21u && pwd) cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) + eval $(/tmp/$USER/plume-scripts/ci-org-and-branch typetools) set echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" displayName: git merge plan @@ -95,7 +95,7 @@ jobs: git config --global core.longpaths true git config --global core.protectNTFS false cd ../jdk21u && git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) + eval $(/tmp/$USER/plume-scripts/ci-org-and-branch typetools) set echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" cd ../jdk21u && git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME} || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57d44cb35f57..e35be06b0643 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,8 +96,8 @@ jobs: # Run `git-clone-related` without a limit on depth, because if the depth is # too small, the merge will fail. Don't use "--filter=blob:none" because that # leads to "fatal: remote error: filter 'combine' not supported". - - name: ci-info - run: /tmp/$USER/plume-scripts/ci-info --debug + - name: ci-org-and-branch + run: /tmp/$USER/plume-scripts/ci-org-and-branch --debug - name: clone-related-jdk21u run: | set -ex @@ -116,7 +116,7 @@ jobs: set -ex cd ../jdk21u git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) + eval $(/tmp/$USER/plume-scripts/ci-org-and-branch typetools) echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" if ! git pull --no-edit "https://github.com/${CI_ORGANIZATION}/jdk" "${CI_BRANCH_NAME}"; then git --version diff --git a/.github/workflows/ci.yml.m4 b/.github/workflows/ci.yml.m4 index 50210af2491f..1f2bd7ff238e 100644 --- a/.github/workflows/ci.yml.m4 +++ b/.github/workflows/ci.yml.m4 @@ -100,8 +100,8 @@ jobs: # Run `git-clone-related` without a limit on depth, because if the depth is # too small, the merge will fail. Don't use "--filter=blob:none" because that # leads to "fatal: remote error: filter 'combine' not supported". - - name: ci-info - run: /tmp/$USER/plume-scripts/ci-info --debug + - name: ci-org-and-branch + run: /tmp/$USER/plume-scripts/ci-org-and-branch --debug - name: clone-related-jdk21u run: | set -ex @@ -120,7 +120,7 @@ jobs: set -ex cd ../jdk21u git status - eval $(/tmp/$USER/plume-scripts/ci-info typetools) + eval $(/tmp/$USER/plume-scripts/ci-org-and-branch typetools) echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" if ! git pull --no-edit "https://github.com/${CI_ORGANIZATION}/jdk" "${CI_BRANCH_NAME}"; then git --version From 147db198ec6a5016d50c4659d9cbd40b6888e84d Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Mon, 25 May 2026 12:15:26 -0700 Subject: [PATCH 088/119] Remove nearly-empty file --- README-merging.el | 1 - 1 file changed, 1 deletion(-) delete mode 100644 README-merging.el diff --git a/README-merging.el b/README-merging.el deleted file mode 100644 index 5b657bd00aaf..000000000000 --- a/README-merging.el +++ /dev/null @@ -1 +0,0 @@ -;; See file diff-resolve.el From 723083f872e4c11359fdd18510b2f217be7e830b Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 26 May 2026 08:53:06 -0700 Subject: [PATCH 089/119] Update qualifiers --- checker-qual.jar | Bin 291739 -> 291748 bytes src/java.base/share/classes/module-info.java | 2 +- .../checker/index/qual/BottomGrowShrink.java | 2 +- .../checker/index/qual/PolyGrowShrink.java | 2 +- .../modifiability/qual/MaybeModifiable.java | 6 +++--- .../modifiability/qual/PolyModifiable.java | 4 ++-- .../modifiability/qual/PolyShrinkable.java | 2 +- ...UnmodParam.java => UnmodifiableParam.java} | 10 +++++----- 8 files changed, 14 insertions(+), 14 deletions(-) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{UnmodParam.java => UnmodifiableParam.java} (66%) diff --git a/checker-qual.jar b/checker-qual.jar index 1d92bd752d579b6ac33721ace7c901bb49fb78d6..92ec2c9758ac4af63571c4096a6db5ad6ebef102 100644 GIT binary patch delta 8323 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≫kNpfVhjkX1lI1_C^W z%ZGE5$(BN>7>>gk>W&KL#T3je#^kSdN6&}w8o`U3+|jeiItsiz5NyPo1TWd_fhAN~ z54IyXbHNDQv8BLf1Uf!a+DF0B5$M=>69uW8a3Sh>qT{MRDKpm-%}13}@W2xt->sm) z!3zziZl$2u3ng{iDCpvW&)*aTdULkSZOHNFVoBIPbb#_cX!>d=1<5>Ex*NLvI9)jE zgMHWh0>OTqG{}uaMtlzyBcs4S+>{_{Pro@9B&u*?BwmiqD@9BS_Y-lj@Wq4&>=&hd zvD%BPMVMaSzB=0aanl$N2pNUj%mqK(c~_eYD?vYT!kSNW%%BmAhrBMx=wg+MTYQy{u$p=b>57fJqT8Q%x2_@}WF-1f(5 zU-gU83BWDv)p=gm3M?<++0^&wK6*H%YX9s3u(Q)w&9@s+t4K(R{2v4f(=QyB_diXk)b6{G*b{sB&Yj-JUa~tQ*pnJ44 zCFmH3Vb|QJGN}gyKPvHycv2uPo|%vth$mt3V=65V#M|9~AWYEXr#zz%G4;6U=LKQn zje!Zq3t-=Ey*UVN=kY{3nb<%z3xhd7vgn1-Oa){^u&6s<(xS$P;PmbK1&)T`7~Nh` z2?9kh7>}L$w~8=@tr+Q^Nxw>?XdrxiD2cuCIt(@Axj@p}4reA{tz0HxfFr;l6jQd2 zZx`_GU$aCa6oYN#i41(c7KP#sx8^Nx=KzXbcs`Dsh!tVGDP!G%3p%_T%h`8q-kONH z^Lr;ED}9Fv>64Yd?>GC_Kfgbt3tg(mY;gcPkuWL*3M2MC#PVy`9yy6|%{UhMreg^U`k)?}q1EgFMx)uMD?Y>Tv5 zWqJ*Lsl$q%jSqE1w6q7Yvaq2Am#Oy@j08Wm{5QJ%DVz_nH4ri?&@%-)KV~Ro2Ecbi zb|C#Qu)wHaFX=`iT9rnu0$u1Yr(!STaZw0!I5Y;&K50QLX8=oMa1M^brZKIfz?2oe zf38GHEIDJr8xIj!vIAgaERMR+zK?*L_BfQjDJC%ur)~fkOyeSmt}B&ByW)4hKIwUs zlHw7R7LUVwwW|-mtzw*@waGCnc*KPBmjXj(drGN%*qd9f}*2$aAv2~RO5m1j(#FbVIj z=hJy$2E9pmC0qzL$=oy|ok>lOC37Q5-5d&(=CX$TO~;IUo==&LDVV2|SrmNFVl_ZJ z6~*@!Q6@bVCv8SH1^cpbI)%N%f8M3yDE`W$^s79yD&&(Cm4es<3^F5dYJCU)>Beh?G; EKeW%9UjP6A delta 8222 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 I{O~3Ae|nmW_5c6? diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 17659d96aa63..275a19414e0b 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -82,8 +82,8 @@ exports org.checkerframework.checker.fenum.qual; exports org.checkerframework.checker.formatter.qual; exports org.checkerframework.checker.guieffect.qual; - exports org.checkerframework.checker.i18n.qual; exports org.checkerframework.checker.i18nformatter.qual; + exports org.checkerframework.checker.i18n.qual; exports org.checkerframework.checker.index.qual; exports org.checkerframework.checker.initialization.qual; exports org.checkerframework.checker.interning.qual; diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java index 2c2dc9cc7349..2b3596199228 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/BottomGrowShrink.java @@ -18,4 +18,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({GrowOnly.class, UncheckedCanShrink.class}) -public @interface BottomGrowableShrink {} +public @interface BottomGrowShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java b/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java index a6786d44a216..6bb99e1af4fc 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java +++ b/src/java.base/share/classes/org/checkerframework/checker/index/qual/PolyGrowShrink.java @@ -19,4 +19,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @PolymorphicQualifier(UnshrinkableRef.class) -public @interface PolyGrowableShrink {} +public @interface PolyGrowShrink {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java index a36b2a03aa74..c4b7e274efda 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java @@ -7,9 +7,9 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. Represents an unknown or - * arbitrary modifiability capability; the checker cannot determine whether the collection is - * growable, shrinkable, or replaceable. + * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. Represents + * an unknown or arbitrary modifiability capability; the checker cannot determine whether the + * collection is growable, shrinkable, or replaceable. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to * {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated type. diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 93c85ea6db3d..517762db7857 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -4,8 +4,8 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkableable}. A polymorphic qualifier for - * all three modifiability hierarchies. + * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkable}. A polymorphic + * qualifier for all three modifiability hierarchies. * *

You should write {@code @PolyModifiable} on methods that preserve or transfer modifiability, * such as {@code List.subList()}, {@code iterator()}, and {@code stream()}. diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java index 252d128e9ed7..9ed1fef83e6b 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyShrinkable.java @@ -19,4 +19,4 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @PolymorphicQualifier(MaybeShrinkable.class) -public @interface PolyShrinkableable {} +public @interface PolyShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java similarity index 66% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java index 7342219e5daf..3f3662d5a767 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodParam.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java @@ -7,10 +7,10 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. This is a syntactic - * sugar for {@link MaybeModifiable}. It is intended to be used on parameters of methods that are - * not designed to change the parameter. This annotation is only allowed to be written within method - * or constructor parameter types, or explicit receiver parameter types. + * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. This is a + * syntactic sugar for {@link MaybeModifiable}. It is intended to be used on parameters of methods + * that are not designed to change the parameter. This annotation is only allowed to be written + * within method or constructor parameter types, or explicit receiver parameter types. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to * {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated type. @@ -20,4 +20,4 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -public @interface UnmodParam {} +public @interface UnmodifiableParam {} From 2e20f49d7054f91c92201952709c3d04c5a8b3ae Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 26 May 2026 09:18:10 -0700 Subject: [PATCH 090/119] Fix broken merge --- .../classes/java/util/AbstractCollection.java | 18 ++++--- .../share/classes/java/util/AbstractList.java | 21 +++++--- .../share/classes/java/util/AbstractMap.java | 12 +++-- .../classes/java/util/AbstractQueue.java | 12 +++-- .../share/classes/java/util/AbstractSet.java | 3 +- .../share/classes/java/util/Collection.java | 3 +- .../share/classes/java/util/Hashtable.java | 21 +++++--- .../classes/java/util/IdentityHashMap.java | 12 +++-- .../share/classes/java/util/Iterator.java | 3 +- .../share/classes/java/util/Map.java | 12 +++-- .../java/util/SequencedCollection.java | 12 +++-- .../share/classes/java/util/SequencedMap.java | 21 +++++--- .../share/classes/java/util/Stack.java | 6 ++- .../share/classes/java/util/WeakHashMap.java | 12 +++-- .../util/concurrent/CopyOnWriteArrayList.java | 54 ++++++++++++------- 15 files changed, 148 insertions(+), 74 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 0d56b52d7d67..caea9e1bc2fa 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -283,7 +283,8 @@ private static T[] finishToArray(T[] r, Iterator it) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); + public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { + throw new UnsupportedOperationException(); } /** @@ -305,7 +306,8 @@ private static T[] finishToArray(T[] r, Iterator it) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); + public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + Iterator it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { @@ -369,7 +371,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Collection c) { boolean modified = false; + public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Collection c) { + boolean modified = false; for (E e : c) if (add(e)) modified = true; @@ -400,7 +403,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); while (it.hasNext()) { @@ -436,7 +440,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); while (it.hasNext()) { @@ -466,7 +471,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); + public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { + Iterator it = iterator(); while (it.hasNext()) { it.next(); it.remove(); diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index 058756423853..ee3a2f87e659 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -142,7 +142,8 @@ protected AbstractList() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { add(size(), e); + public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { + add(size(), e); return true; } @@ -169,7 +170,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); + public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { + throw new UnsupportedOperationException(); } /** @@ -187,7 +189,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); + public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { + throw new UnsupportedOperationException(); } /** @@ -202,7 +205,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); + public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { + throw new UnsupportedOperationException(); } @@ -283,7 +287,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { removeRange(0, size()); + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { + removeRange(0, size()); } /** @@ -308,7 +313,8 @@ protected AbstractList() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); + public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { + rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); @@ -654,7 +660,8 @@ public int hashCode(@GuardSatisfied AbstractList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); + protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i this, @GuardSatisfi @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied AbstractMap this, K key, V value) { throw new UnsupportedOperationException(); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied AbstractMap this, K key, V value) { + throw new UnsupportedOperationException(); } /** @@ -277,7 +278,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); + public @Nullable V remove(@Shrinkable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + Iterator> i = entrySet().iterator(); Entry correctEntry = null; if (key==null) { while (correctEntry==null && i.hasNext()) { @@ -323,7 +325,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) + public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this, Map m) { + for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); } @@ -341,7 +344,8 @@ public void putAll(@Growable @Replaceable @GuardSatisfied AbstractMap this */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { entrySet().clear(); + public void clear(@Shrinkable @GuardSatisfied AbstractMap this) { + entrySet().clear(); } diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index 67de85968221..518de35e56bd 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -107,7 +107,8 @@ public abstract class AbstractQueue @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { if (offer(e)) + public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { + if (offer(e)) return true; else throw new IllegalStateException("Queue full"); @@ -126,7 +127,8 @@ public boolean add(@Growable @GuardSatisfied AbstractQueue this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { E x = poll(); + public E remove(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { + E x = poll(); if (x != null) return x; else @@ -162,7 +164,8 @@ public E element(@GuardSatisfied @NonEmpty AbstractQueue this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) { while (poll() != null) + public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) { + while (poll() != null) ; } @@ -197,7 +200,8 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractQueue this) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractQueue this, Collection c) { if (c == null) + public boolean addAll(@Growable @GuardSatisfied AbstractQueue this, Collection c) { + if (c == null) throw new NullPointerException(); if (c == this) throw new IllegalArgumentException(); diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index d6a689363555..bc52ec9e9f9e 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -179,7 +179,8 @@ public int hashCode(@GuardSatisfied AbstractSet this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { + Objects.requireNonNull(c); boolean modified = false; if (size() > c.size()) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index cf08a7d6292a..aee783f15f80 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -624,7 +624,8 @@ default T[] toArray(Collection this, IntFunction generator) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); + default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { + Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); while (each.hasNext()) { diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 74b64b742139..5a611bc50287 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -548,7 +548,8 @@ private void addEntry(int hash, K key, V value, int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized @Nullable V remove(@Shrinkable @GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { Entry tab[] = table; + public synchronized @Nullable V remove(@Shrinkable @GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { + Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") @@ -581,7 +582,8 @@ private void addEntry(int hash, K key, V value, int index) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable this, Map t) { for (Map.Entry e : t.entrySet()) + public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable this, Map t) { + for (Map.Entry e : t.entrySet()) put(e.getKey(), e.getValue()); } @@ -590,7 +592,8 @@ public synchronized void putAll(@Growable @Replaceable @GuardSatisfied Hashtable */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) { Entry tab[] = table; + public synchronized void clear(@Shrinkable @GuardSatisfied Hashtable this) { + Entry tab[] = table; for (int index = tab.length; --index >= 0; ) tab[index] = null; modCount++; @@ -1006,7 +1009,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized V putIfAbsent(@Growable Hashtable this, K key, V value) { Objects.requireNonNull(value); + public synchronized V putIfAbsent(@Growable Hashtable this, K key, V value) { + Objects.requireNonNull(value); // Makes sure the key is not already in the hashtable. Entry tab[] = table; @@ -1031,7 +1035,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Objects.requireNonNull(value); + public synchronized boolean remove(@Shrinkable Hashtable this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + Objects.requireNonNull(value); Entry tab[] = table; int hash = key.hashCode(); @@ -1057,7 +1062,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized boolean replace(@Replaceable Hashtable this, K key, V oldValue, V newValue) { Objects.requireNonNull(oldValue); + public synchronized boolean replace(@Replaceable Hashtable this, K key, V oldValue, V newValue) { + Objects.requireNonNull(oldValue); Objects.requireNonNull(newValue); Entry tab[] = table; int hash = key.hashCode(); @@ -1080,7 +1086,8 @@ public synchronized void replaceAll(@Replaceable Hashtable this, BiFunctio @Override // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized V replace(@Replaceable Hashtable this, K key, V value) { Objects.requireNonNull(value); + public synchronized V replace(@Replaceable Hashtable this, K key, V value) { + Objects.requireNonNull(value); Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 193d30e3e48e..aca3dfd6ab7a 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -469,7 +469,8 @@ private boolean containsMapping(@UnknownSignedness @GuardSatisfied @Nullable Obj @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, K key, V value) { final Object k = maskNull(key); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, K key, V value) { + final Object k = maskNull(key); retryAfterResize: for (;;) { final Object[] tab = table; @@ -551,7 +552,8 @@ private boolean resize(int newCapacity) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, Map m) { int n = m.size(); + public void putAll(@Growable @Replaceable @GuardSatisfied IdentityHashMap this, Map m) { + int n = m.size(); if (n == 0) return; if (n > size) @@ -574,7 +576,8 @@ private boolean resize(int newCapacity) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); + public @Nullable V remove(@Shrinkable @GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + Object k = maskNull(key); Object[] tab = table; int len = tab.length; int i = hash(k, len); @@ -671,7 +674,8 @@ private void closeDeletion(int d) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied IdentityHashMap this) { modCount++; + public void clear(@Shrinkable @GuardSatisfied IdentityHashMap this) { + modCount++; Object[] tab = table; for (int i = 0; i < tab.length; i++) tab[i] = null; diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index 798b8538efee..c1dd90bf6868 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -122,7 +122,8 @@ public interface Iterator { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { throw new UnsupportedOperationException("remove"); + default void remove(@Shrinkable @GuardSatisfied @CanShrink Iterator this) { + throw new UnsupportedOperationException("remove"); } /** diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 90114282fb60..df217822e820 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -908,7 +908,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V value) { V v = get(key); + default @Nullable V putIfAbsent(@Growable Map this, K key, V value) { + V v = get(key); if (v == null) { v = put(key, value); } @@ -953,7 +954,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Object curValue = get(key); + default boolean remove(@Shrinkable Map this, @GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { + Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { return false; @@ -1004,7 +1006,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V oldValue, V newValue) { Object curValue = get(key); + default boolean replace(@Replaceable Map this, K key, V oldValue, V newValue) { + Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { return false; @@ -1053,7 +1056,8 @@ default void replaceAll(@Replaceable Map this, BiFunction this, K key, V value) { V curValue; + default @Nullable V replace(@Replaceable Map this, K key, V value) { + V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); } diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index c1f051acea37..8df7e5539589 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -113,7 +113,8 @@ public interface SequencedCollection extends Collection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addFirst(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); + default void addFirst(@Growable SequencedCollection this, E e) { + throw new UnsupportedOperationException(); } /** @@ -132,7 +133,8 @@ public interface SequencedCollection extends Collection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addLast(@Growable SequencedCollection this, E e) { throw new UnsupportedOperationException(); + default void addLast(@Growable SequencedCollection this, E e) { + throw new UnsupportedOperationException(); } /** @@ -186,7 +188,8 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.iterator(); + default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { + var it = this.iterator(); E e = it.next(); it.remove(); return e; @@ -209,7 +212,8 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); + default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { + var it = this.reversed().iterator(); E e = it.next(); it.remove(); return e; diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index a7f861d733f7..3f69c702610f 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -200,7 +200,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { var it = entrySet().iterator(); + default Map.Entry pollFirstEntry(@Shrinkable SequencedMap this) { + var it = entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); it.remove(); @@ -226,7 +227,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { var it = reversed().entrySet().iterator(); + default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { + var it = reversed().entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); it.remove(); @@ -253,7 +255,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); + default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { + throw new UnsupportedOperationException(); } /** @@ -273,7 +276,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); + default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { + throw new UnsupportedOperationException(); } /** @@ -292,7 +296,8 @@ default Map.Entry lastEntry() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyShrink @Ungrowable SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { + default @PolyShrink @Ungrowable SequencedSet sequencedKeySet(@PolyShrink SequencedMap this) { + class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { Collection view() { return SequencedMap.this.keySet(); } @@ -328,7 +333,8 @@ public int hashCode() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyShrink @Ungrowable SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { + default @PolyShrink @Ungrowable SequencedCollection sequencedValues(@PolyShrink SequencedMap this) { + class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { Collection view() { return SequencedMap.this.values(); } @@ -355,7 +361,8 @@ public SequencedCollection reversed() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default @PolyShrink @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { class SeqEntrySet extends AbstractMap.ViewCollection> + default @PolyShrink @Ungrowable SequencedSet> sequencedEntrySet(@PolyModifiable SequencedMap this) { + class SeqEntrySet extends AbstractMap.ViewCollection> implements SequencedSet> { Collection> view() { return SequencedMap.this.entrySet(); diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 301b50ae5a0d..ab8c4b91a1da 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -82,7 +82,8 @@ public class Stack extends Vector { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E push(@Growable @GuardSatisfied Stack this, E item) { addElement(item); + public E push(@Growable @GuardSatisfied Stack this, E item) { + addElement(item); return item; } @@ -97,7 +98,8 @@ public class Stack extends Vector { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public synchronized E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Stack this) { E obj; + public synchronized E pop(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink Stack this) { + E obj; int len = size(); obj = peek(); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 8ad6b1cf77aa..462fbe1d3325 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -494,7 +494,8 @@ Entry getEntry(Object key) { @EnsuresKeyFor(value={"#1"}, map={"this"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V put(@Growable @Replaceable @GuardSatisfied WeakHashMap this, K key, V value) { Object k = maskNull(key); + public @Nullable V put(@Growable @Replaceable @GuardSatisfied WeakHashMap this, K key, V value) { + Object k = maskNull(key); int h = hash(k); Entry[] tab = getTable(); int i = indexFor(h, tab.length); @@ -587,7 +588,8 @@ private void transfer(Entry[] src, Entry[] dest) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this, Map m) { int numKeysToBeAdded = m.size(); + public void putAll(@Growable @Replaceable @GuardSatisfied WeakHashMap this, Map m) { + int numKeysToBeAdded = m.size(); if (numKeysToBeAdded == 0) return; @@ -637,7 +639,8 @@ private void transfer(Entry[] src, Entry[] dest) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable V remove(@Shrinkable @GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); + public @Nullable V remove(@Shrinkable @GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { + Object k = maskNull(key); int h = hash(k); Entry[] tab = getTable(); int i = indexFor(h, tab.length); @@ -697,7 +700,8 @@ boolean removeMapping(Object o) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied WeakHashMap this) { // clear out ref queue. We don't need to expunge entries + public void clear(@Shrinkable @GuardSatisfied WeakHashMap this) { + // clear out ref queue. We don't need to expunge entries // since table is getting cleared. while (queue.poll() != null) ; 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 79b0c90ebf95..0679f8f9ad49 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -485,7 +485,8 @@ public E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { + public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { + synchronized (lock) { Object[] es = getArray(); E oldValue = elementAt(es, index); @@ -508,7 +509,8 @@ public E set(@Replaceable CopyOnWriteArrayList this, int index, E element) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { + public boolean add(@Growable CopyOnWriteArrayList this, E e) { + synchronized (lock) { Object[] es = getArray(); int len = es.length; es = Arrays.copyOf(es, len + 1); @@ -527,7 +529,8 @@ public boolean add(@Growable CopyOnWriteArrayList this, E e) { synchro */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable CopyOnWriteArrayList this, int index, E element) { synchronized (lock) { + public void add(@Growable CopyOnWriteArrayList this, int index, E element) { + synchronized (lock) { Object[] es = getArray(); int len = es.length; if (index > len || index < 0) @@ -554,7 +557,8 @@ public void add(@Growable CopyOnWriteArrayList this, int index, E element) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable CopyOnWriteArrayList this, E e) { add(0, e); + public void addFirst(@Growable CopyOnWriteArrayList this, E e) { + add(0, e); } /** @@ -564,7 +568,8 @@ public void add(@Growable CopyOnWriteArrayList this, int index, E element) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable CopyOnWriteArrayList this, E e) { synchronized (lock) { + public void addLast(@Growable CopyOnWriteArrayList this, E e) { + synchronized (lock) { add(getArray().length, e); } } @@ -578,7 +583,8 @@ public void addLast(@Growable CopyOnWriteArrayList this, E e) { synchr */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { synchronized (lock) { + public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { + synchronized (lock) { Object[] es = getArray(); int len = es.length; E oldValue = elementAt(es, index); @@ -605,7 +611,8 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList t */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { + public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { + synchronized (lock) { if (getArray().length == 0) throw new NoSuchElementException(); else @@ -621,7 +628,8 @@ public E removeFirst(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWrit */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { + public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWriteArrayList this) { + synchronized (lock) { int size = getArray().length; if (size == 0) throw new NoSuchElementException(); @@ -644,7 +652,8 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink CopyOnWrite */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@Shrinkable @CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] snapshot = getArray(); + public boolean remove(@Shrinkable @CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { + Object[] snapshot = getArray(); int index = indexOfRange(o, snapshot, 0, snapshot.length); return index >= 0 && remove(o, snapshot, index); } @@ -725,7 +734,8 @@ void removeRange(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int fr */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addIfAbsent(@Growable CopyOnWriteArrayList this, E e) { Object[] snapshot = getArray(); + public boolean addIfAbsent(@Growable CopyOnWriteArrayList this, E e) { + Object[] snapshot = getArray(); return indexOfRange(e, snapshot, 0, snapshot.length) < 0 && addIfAbsent(e, snapshot); } @@ -794,7 +804,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); + public boolean removeAll(@Shrinkable @CanShrink CopyOnWriteArrayList this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -816,7 +827,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); + public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this, Collection c) { + Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } @@ -833,7 +845,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = c.toArray(); + public int addAllAbsent(@Growable CopyOnWriteArrayList this, Collection c) { + Object[] cs = c.toArray(); if (c.getClass() != ArrayList.class) { cs = cs.clone(); } @@ -865,7 +878,8 @@ public boolean containsAll(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { + public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList this) { + synchronized (lock) { setArray(new Object[0]); } } @@ -882,7 +896,8 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink CopyOnWriteArrayList */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable CopyOnWriteArrayList this, Collection c) { Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? + public boolean addAll(@Growable CopyOnWriteArrayList this, Collection c) { + Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? ((CopyOnWriteArrayList)c).getArray() : c.toArray(); if (cs.length == 0) return false; @@ -920,7 +935,8 @@ public boolean addAll(@Growable CopyOnWriteArrayList this, Collection this, int index, Collection c) { Object[] cs = c.toArray(); + public boolean addAll(@Growable CopyOnWriteArrayList this, int index, Collection c) { + Object[] cs = c.toArray(); synchronized (lock) { Object[] es = getArray(); int len = es.length; @@ -961,7 +977,8 @@ public void forEach(Consumer action) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeIf(@Shrinkable @CanShrink CopyOnWriteArrayList this, Predicate filter) { Objects.requireNonNull(filter); + public boolean removeIf(@Shrinkable @CanShrink CopyOnWriteArrayList this, Predicate filter) { + Objects.requireNonNull(filter); return bulkRemove(filter); } @@ -1035,7 +1052,8 @@ void replaceAllRange(UnaryOperator operator, int i, int end) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void sort(@Replaceable CopyOnWriteArrayList this, Comparator c) { synchronized (lock) { + public void sort(@Replaceable CopyOnWriteArrayList this, Comparator c) { + synchronized (lock) { sortRange(c, 0, getArray().length); } } From f00d52b4df7254fe3a331c132b1d522bea2fd4e9 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Tue, 26 May 2026 15:44:30 -0700 Subject: [PATCH 091/119] add iteratorPolyMod to Collections. --- src/java.base/share/classes/java/util/Collections.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 3e21cc2578b1..7a710a5d93b2 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -1090,7 +1090,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @SuppressWarnings("unchecked") @SideEffectFree - public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@PolyGrowShrink @PolyNonEmpty Collection c) { + public static @IteratorPolyMod @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@PolyGrowShrink @PolyNonEmpty Collection c) { if (c.getClass() == UnmodifiableCollection.class) { return (Collection) c; } @@ -1334,7 +1334,7 @@ public E removeLast() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@PolyNonEmpty Set s) { + public static @IteratorPolyMod @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@PolyNonEmpty Set s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSet.class) { return (Set) s; From a741392ca01a0354f82dc7a700483349b6b1d3df Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 26 May 2026 18:18:40 -0700 Subject: [PATCH 092/119] Better diagnostics --- .azure/azure-pipelines.yml | 2 ++ .azure/azure-pipelines.yml.m4 | 2 ++ .github/workflows/ci.yml | 10 ++-------- .github/workflows/ci.yml.m4 | 10 ++-------- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index b8c08d344110..4f935f4e0925 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -16,6 +16,7 @@ jobs: pwd ls -al env | sort + set displayName: show environment - bash: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors displayName: configure @@ -41,6 +42,7 @@ jobs: pwd ls -al env | sort + set displayName: show environment - bash: | set -ex diff --git a/.azure/azure-pipelines.yml.m4 b/.azure/azure-pipelines.yml.m4 index 1dc0ed8481b9..4ad527e5a876 100644 --- a/.azure/azure-pipelines.yml.m4 +++ b/.azure/azure-pipelines.yml.m4 @@ -19,6 +19,7 @@ jobs: pwd ls -al env | sort + set displayName: show environment - bash: pwd && ls && bash ./configure --with-jtreg=/usr/share/jtreg --disable-warnings-as-errors displayName: configure @@ -44,6 +45,7 @@ jobs: pwd ls -al env | sort + set displayName: show environment - bash: | set -ex diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f2599aa288d..6d7f8d909952 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,10 +38,7 @@ jobs: git config --get remote.origin.url || true pwd ls -al - echo "HOME=${HOME}" - echo "USER=${USER}" - echo "SHELL=${SHELL}" - echo "GITHUB_WORKSPACE=${GITHUB_WORKSPACE}" + set - name: configure run: | pwd @@ -65,10 +62,7 @@ jobs: git config --get remote.origin.url || true pwd ls -al - echo "HOME=${HOME}" - echo "USER=${USER}" - echo "SHELL=${SHELL}" - echo "GITHUB_WORKSPACE=${GITHUB_WORKSPACE}" + set - name: clone git-scripts run: | set -ex diff --git a/.github/workflows/ci.yml.m4 b/.github/workflows/ci.yml.m4 index ed479aee7960..c61b6642a429 100644 --- a/.github/workflows/ci.yml.m4 +++ b/.github/workflows/ci.yml.m4 @@ -42,10 +42,7 @@ jobs: git config --get remote.origin.url || true pwd ls -al - echo "HOME=${HOME}" - echo "USER=${USER}" - echo "SHELL=${SHELL}" - echo "GITHUB_WORKSPACE=${GITHUB_WORKSPACE}" + set - name: configure run: | pwd @@ -69,10 +66,7 @@ jobs: git config --get remote.origin.url || true pwd ls -al - echo "HOME=${HOME}" - echo "USER=${USER}" - echo "SHELL=${SHELL}" - echo "GITHUB_WORKSPACE=${GITHUB_WORKSPACE}" + set - name: clone git-scripts run: | set -ex From 6fcedc69d38405bdb145d756f8aee4ef787fd20a Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 27 May 2026 07:37:34 -0700 Subject: [PATCH 093/119] Fix bad merge --- .../share/classes/java/lang/Iterable.java | 3 +- .../classes/java/util/AbstractCollection.java | 17 +++---- .../share/classes/java/util/AbstractList.java | 17 +++---- .../share/classes/java/util/AbstractMap.java | 17 +++---- .../java/util/AbstractSequentialList.java | 7 +-- .../share/classes/java/util/AbstractSet.java | 5 +- .../share/classes/java/util/Collection.java | 28 ++++++----- .../share/classes/java/util/Collections.java | 47 ++++++++++--------- .../share/classes/java/util/HashMap.java | 1 + .../share/classes/java/util/HashSet.java | 1 + .../classes/java/util/LinkedHashSet.java | 1 + .../share/classes/java/util/List.java | 32 +++++++------ .../share/classes/java/util/Map.java | 28 +++++------ .../share/classes/java/util/Set.java | 24 +++++----- .../util/concurrent/ConcurrentHashMap.java | 6 ++- .../java/util/concurrent/ConcurrentMap.java | 5 +- .../util/concurrent/LinkedTransferQueue.java | 17 +++---- .../util/concurrent/SynchronousQueue.java | 17 +++---- 18 files changed, 148 insertions(+), 125 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Iterable.java b/src/java.base/share/classes/java/lang/Iterable.java index 2b0cacbbfbc6..8a6b8658e80e 100644 --- a/src/java.base/share/classes/java/lang/Iterable.java +++ b/src/java.base/share/classes/java/lang/Iterable.java @@ -25,6 +25,7 @@ package java.lang; import org.checkerframework.checker.index.qual.PolyGrowShrink; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.common.aliasing.qual.NonLeaked; import org.checkerframework.framework.qual.AnnotatedFor; @@ -51,7 +52,7 @@ public interface Iterable { * * @return an Iterator. */ - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Iterable this); + @MaybeModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Iterable this); /** * Performs the given action for each element of the {@code Iterable} diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 7e78d94dffc5..68cc5df6677b 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -105,10 +106,10 @@ protected AbstractCollection() { * @return an iterator over the elements contained in this collection */ @SideEffectFree - public abstract @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractCollection this); + public abstract @MaybeModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty AbstractCollection this); @Pure - public abstract @NonNegative int size(@GuardSatisfied AbstractCollection this); + public abstract @NonNegative int size(@MaybeModifiable @GuardSatisfied AbstractCollection this); /** * {@inheritDoc} @@ -118,7 +119,7 @@ protected AbstractCollection() { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - public boolean isEmpty(@GuardSatisfied AbstractCollection this) { + public boolean isEmpty(@MaybeModifiable @GuardSatisfied AbstractCollection this) { return size() == 0; } @@ -134,7 +135,7 @@ public boolean isEmpty(@GuardSatisfied AbstractCollection this) { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean contains(@MaybeModifiable @GuardSatisfied AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) @@ -172,7 +173,7 @@ public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisf * } */ @SideEffectFree - public @PolyNull @PolySigned Object[] toArray(AbstractCollection<@PolyNull @PolySigned E> this) { + public @PolyNull @PolySigned Object[] toArray(@MaybeModifiable AbstractCollection<@PolyNull @PolySigned E> this) { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator it = iterator(); @@ -213,7 +214,7 @@ public boolean contains(@GuardSatisfied AbstractCollection this, @GuardSatisf * @throws NullPointerException {@inheritDoc} */ @SuppressWarnings("unchecked") - public @Nullable T [] toArray(@PolyNull T [] a) { + public @Nullable T [] toArray(@MaybeModifiable @PolyNull T [] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : @@ -346,7 +347,7 @@ public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Ab * @see #contains(Object) */ @Pure - public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSatisfied Collection c) { + public boolean containsAll(@MaybeModifiable @GuardSatisfied AbstractCollection this, @GuardSatisfied Collection c) { for (Object e : c) if (!contains(e)) return false; @@ -496,7 +497,7 @@ public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Abstra * @return a string representation of this collection */ @SideEffectFree - public String toString(@GuardSatisfied AbstractCollection this) { + public String toString(@MaybeModifiable @GuardSatisfied AbstractCollection this) { Iterator it = iterator(); if (! it.hasNext()) return "[]"; diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index db68cad822a3..ddcb01da7045 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -152,7 +153,7 @@ public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Pure - public abstract E get(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index); + public abstract E get(@MaybeModifiable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index); /** * {@inheritDoc} @@ -226,7 +227,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In */ @Pure @StaticallyExecutable - public @GTENegativeOne int indexOf(@GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { + public @GTENegativeOne int indexOf(@MaybeModifiable @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(); if (o==null) { while (it.hasNext()) @@ -254,7 +255,7 @@ public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @In */ @Pure @StaticallyExecutable - public @GTENegativeOne int lastIndexOf(@GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { + public @GTENegativeOne int lastIndexOf(@MaybeModifiable @GuardSatisfied AbstractList this, @GuardSatisfied @UnknownSignedness Object o) { ListIterator it = listIterator(size()); if (o==null) { while (it.hasPrevious()) @@ -347,7 +348,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) { return new Itr(); } @@ -359,7 +360,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * * @see #listIterator(int) */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) { return listIterator(0); } @@ -386,7 +387,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this, final @IndexOrHigh({"this"}) int index) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this, final @IndexOrHigh({"this"}) int index) { rangeCheckForAdd(index); return new ListItr(index); @@ -602,7 +603,7 @@ static void subListRangeCheck(int fromIndex, int toIndex, int size) { * @return {@code true} if the specified object is equal to this list */ @Pure - public boolean equals(@GuardSatisfied AbstractList this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@MaybeModifiable @GuardSatisfied AbstractList this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; if (!(o instanceof List)) @@ -630,7 +631,7 @@ public boolean equals(@GuardSatisfied AbstractList this, @GuardSatisfied @Nul * @return the hash code value for this list */ @Pure - public int hashCode(@GuardSatisfied AbstractList this) { + public int hashCode(@MaybeModifiable @GuardSatisfied AbstractList this) { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 573b3c582d56..8751957d9967 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -115,7 +116,7 @@ protected AbstractMap() { * This implementation returns {@code entrySet().size()}. */ @Pure - public @NonNegative int size(@GuardSatisfied AbstractMap this) { + public @NonNegative int size(@MaybeModifiable @GuardSatisfied AbstractMap this) { return entrySet().size(); } @@ -127,7 +128,7 @@ protected AbstractMap() { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - public boolean isEmpty(@GuardSatisfied AbstractMap this) { + public boolean isEmpty(@MaybeModifiable @GuardSatisfied AbstractMap this) { return size() == 0; } @@ -145,7 +146,7 @@ public boolean isEmpty(@GuardSatisfied AbstractMap this) { * @throws NullPointerException {@inheritDoc} */ @Pure - public boolean containsValue(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object value) { + public boolean containsValue(@MaybeModifiable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object value) { Iterator> i = entrySet().iterator(); if (value==null) { while (i.hasNext()) { @@ -179,7 +180,7 @@ public boolean containsValue(@GuardSatisfied AbstractMap this, @GuardSatis */ @Pure @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) - public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { + public boolean containsKey(@MaybeModifiable @GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { @@ -212,7 +213,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi * @throws NullPointerException {@inheritDoc} */ @Pure - public @Nullable V get(@GuardSatisfied AbstractMap this, @UnknownSignedness @GuardSatisfied Object key) { + public @Nullable V get(@MaybeModifiable @GuardSatisfied AbstractMap this, @UnknownSignedness @GuardSatisfied Object key) { Iterator> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { @@ -554,7 +555,7 @@ public boolean contains(@UnknownSignedness Object v) { * @return {@code true} if the specified object is equal to this map */ @Pure - public boolean equals(@GuardSatisfied AbstractMap this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@MaybeModifiable @GuardSatisfied AbstractMap this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; @@ -601,7 +602,7 @@ public boolean equals(@GuardSatisfied AbstractMap this, @GuardSatisfied @N * @see Set#equals(Object) */ @Pure - public int hashCode(@GuardSatisfied AbstractMap this) { + public int hashCode(@MaybeModifiable @GuardSatisfied AbstractMap this) { int h = 0; for (Entry entry : entrySet()) h += entry.hashCode(); @@ -621,7 +622,7 @@ public int hashCode(@GuardSatisfied AbstractMap this) { * @return a string representation of this map */ @SideEffectFree - public String toString(@GuardSatisfied AbstractMap this) { + public String toString(@MaybeModifiable @GuardSatisfied AbstractMap this) { Iterator> i = entrySet().iterator(); if (! i.hasNext()) return "{}"; diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 17fd69a3b152..5dd09a930be1 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -105,7 +106,7 @@ protected AbstractSequentialList() { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Pure - public E get(@GuardSatisfied AbstractSequentialList this, int index) { + public E get(@MaybeModifiable @GuardSatisfied AbstractSequentialList this, int index) { try { return listIterator(index).next(); } catch (NoSuchElementException exc) { @@ -267,7 +268,7 @@ public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequent * @return an iterator over the elements in this list (in proper sequence) */ @SideEffectFree - public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractSequentialList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractSequentialList this) { return listIterator(); } @@ -281,5 +282,5 @@ public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequent * sequence) * @throws IndexOutOfBoundsException {@inheritDoc} */ - public abstract @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink AbstractSequentialList this, int index); + public abstract @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable AbstractSequentialList this, int index); } diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index bc52ec9e9f9e..fa3f8e9e2d48 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.UnknownSignedness; @@ -95,7 +96,7 @@ protected AbstractSet() { * @return {@code true} if the specified object is equal to this set */ @Pure - public boolean equals(@GuardSatisfied AbstractSet this, @GuardSatisfied @Nullable Object o) { + public boolean equals(@MaybeModifiable @GuardSatisfied AbstractSet this, @GuardSatisfied @Nullable Object o) { if (o == this) return true; @@ -129,7 +130,7 @@ public boolean equals(@GuardSatisfied AbstractSet this, @GuardSatisfied @Null * @see Set#equals(Object) */ @Pure - public int hashCode(@GuardSatisfied AbstractSet this) { + public int hashCode(@MaybeModifiable @GuardSatisfied AbstractSet this) { int h = 0; Iterator i = iterator(); while (i.hasNext()) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index aee783f15f80..0e80771451f7 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -292,7 +293,7 @@ public interface Collection extends Iterable { * @return the number of elements in this collection */ @Pure - @NonNegative int size(@GuardSatisfied Collection this); + @NonNegative int size(@MaybeModifiable @GuardSatisfied Collection this); /** * Returns {@code true} if this collection contains no elements. @@ -301,7 +302,7 @@ public interface Collection extends Iterable { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied Collection this); + boolean isEmpty(@MaybeModifiable @GuardSatisfied Collection this); /** * Returns {@code true} if this collection contains the specified element. @@ -324,7 +325,7 @@ public interface Collection extends Iterable { "(though I think a nicer specification would be to return false in that case)"}) @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@GuardSatisfied Collection this, @GuardSatisfied @UnknownSignedness Object o); + boolean contains(@MaybeModifiable @GuardSatisfied Collection this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns an iterator over the elements in this collection. There are no @@ -335,7 +336,7 @@ public interface Collection extends Iterable { * @return an {@code Iterator} over the elements in this collection */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Collection this); + @MaybeModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Collection this); /** * Returns an array containing all of the elements in this collection. @@ -364,7 +365,7 @@ public interface Collection extends Iterable { "methods, because the most useful type for toArray is not expressible", "in the surface syntax that the nullness annotations support."}) @SideEffectFree - @PolyNull @PolySigned Object[] toArray(Collection<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(@MaybeModifiable Collection<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this collection; @@ -417,7 +418,8 @@ public interface Collection extends Iterable { * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ - @Nullable T[] toArray(Collection this, @PolyNull T[] a); + @SideEffectFree + @Nullable T[] toArray(@MaybeModifiable Collection this, @PolyNull T[] a); /** * Returns an array containing all of the elements in this collection, @@ -455,7 +457,7 @@ public interface Collection extends Iterable { * @since 11 */ @SideEffectFree - default T[] toArray(Collection this, IntFunction generator) { + default T[] toArray(@MaybeModifiable Collection this, IntFunction generator) { return toArray(generator.apply(0)); } @@ -543,7 +545,7 @@ default T[] toArray(Collection this, IntFunction generator) { * @see #contains(Object) */ @Pure - boolean containsAll(@GuardSatisfied Collection this, @GuardSatisfied Collection c); + boolean containsAll(@MaybeModifiable @GuardSatisfied Collection this, @GuardSatisfied Collection c); /** * Adds all of the elements in the specified collection to this collection @@ -709,7 +711,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t * @see List#equals(Object) */ @Pure - boolean equals(@GuardSatisfied Collection this, @GuardSatisfied @Nullable @UnknownSignedness Object o); + boolean equals(@MaybeModifiable @GuardSatisfied Collection this, @GuardSatisfied @Nullable @UnknownSignedness Object o); /** * Returns the hash code value for this collection. While the @@ -727,7 +729,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t * @see Object#equals(Object) */ @Pure - int hashCode(@GuardSatisfied Collection this); + int hashCode(@MaybeModifiable @GuardSatisfied Collection this); /** * Creates a {@link Spliterator} over the elements in this collection. @@ -781,7 +783,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t */ @SideEffectFree @Override - default Spliterator spliterator(Collection this) { + default Spliterator spliterator(@MaybeModifiable Collection this) { return Spliterators.spliterator(this, 0); } @@ -801,7 +803,7 @@ default Spliterator spliterator(Collection this) { * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - default @PolyNonEmpty Stream stream(@PolyNonEmpty Collection this) { + default @PolyNonEmpty Stream stream(@MaybeModifiable @PolyNonEmpty Collection this) { return StreamSupport.stream(spliterator(), false); } @@ -823,7 +825,7 @@ default Spliterator spliterator(Collection this) { * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - default Stream parallelStream(Collection this) { + default Stream parallelStream(@MaybeModifiable Collection this) { return StreamSupport.stream(spliterator(), true); } } diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 0ea0478261b5..1426e5d2cd0b 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -249,7 +250,7 @@ public static void sort(@IteratorPolyMod @Replaceable List list, @Nullabl * with the elements of the list. */ public static - int binarySearch(List> list, T key) { + int binarySearch(@MaybeModifiable List> list, T key) { if (list instanceof RandomAccess || list.size()> list, T key) { } private static - int indexedBinarySearch(List> list, T key) { + int indexedBinarySearch(@MaybeModifiable List> list, T key) { int low = 0; int high = list.size()-1; @@ -277,7 +278,7 @@ else if (cmp > 0) } private static - int iteratorBinarySearch(List> list, T key) + int iteratorBinarySearch(@MaybeModifiable List> list, T key) { int low = 0; int high = list.size()-1; @@ -354,7 +355,7 @@ private static T get(ListIterator i, int index) { * elements of the list using this comparator. */ @SuppressWarnings("unchecked") - public static int binarySearch(List list, T key, @Nullable Comparator c) { + public static int binarySearch(@MaybeModifiable List list, T key, @Nullable Comparator c) { if (c==null) return binarySearch((List>) list, key); @@ -364,7 +365,7 @@ public static int binarySearch(List list, T key, @Nullable Comp return Collections.iteratorBinarySearch(list, key, c); } - private static int indexedBinarySearch(List l, T key, Comparator c) { + private static int indexedBinarySearch(@MaybeModifiable List l, T key, Comparator c) { int low = 0; int high = l.size()-1; @@ -383,7 +384,7 @@ else if (cmp > 0) return -(low + 1); // key not found } - private static int iteratorBinarySearch(List l, T key, Comparator c) { + private static int iteratorBinarySearch(@MaybeModifiable List l, T key, Comparator c) { int low = 0; int high = l.size()-1; ListIterator i = l.listIterator(); @@ -618,7 +619,7 @@ public static void fill(@IteratorPolyMod @Replaceable @GuardSatisfied List void copy(@IteratorPolyMod @Replaceable List dest, List src) { + public static void copy(@IteratorPolyMod @Replaceable List dest, @MaybeModifiable List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -661,7 +662,7 @@ public static void copy(@IteratorPolyMod @Replaceable List dest, */ @Pure @StaticallyExecutable - public static > T min(Collection coll) { + public static > T min(@MaybeModifiable Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); @@ -699,7 +700,7 @@ public static > T min(Collection T min(Collection coll, @Nullable Comparator comp) { + public static T min(@MaybeModifiable Collection coll, @Nullable Comparator comp) { if (comp==null) return (T)min((Collection>) coll); @@ -738,7 +739,7 @@ public static T min(Collection coll, @Nullable Comparator> T max(Collection coll) { + public static > T max(@MaybeModifiable Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); @@ -776,7 +777,7 @@ public static > T max(Collection T max(Collection coll, @Nullable Comparator comp) { + public static T max(@MaybeModifiable Collection coll, @Nullable Comparator comp) { if (comp==null) return (T)max((Collection>) coll); @@ -974,7 +975,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @Pure @StaticallyExecutable - public static @GTENegativeOne int indexOfSubList(@GuardSatisfied List source, @GuardSatisfied List target) { + public static @GTENegativeOne int indexOfSubList(@MaybeModifiable @GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; @@ -1029,7 +1030,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @Pure @StaticallyExecutable - public static @GTENegativeOne int lastIndexOfSubList(@GuardSatisfied List source, @GuardSatisfied List target) { + public static @GTENegativeOne int lastIndexOfSubList(@MaybeModifiable @GuardSatisfied List source, @GuardSatisfied List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; @@ -1093,7 +1094,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @SuppressWarnings("unchecked") @SideEffectFree - public static @IteratorPolyMod @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@PolyGrowShrink @PolyNonEmpty Collection c) { + public static @IteratorPolyMod @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { if (c.getClass() == UnmodifiableCollection.class) { return (Collection) c; } @@ -1339,7 +1340,7 @@ public E removeLast() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @IteratorPolyMod @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@PolyNonEmpty Set s) { + public static @IteratorPolyMod @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@MaybeModifiable @PolyNonEmpty Set s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSet.class) { return (Set) s; @@ -1433,7 +1434,7 @@ public SequencedSet reversed() { * returned. * @return an unmodifiable view of the specified sorted set. */ - public static @Unmodifiable @PolyNonEmpty SortedSet unmodifiableSortedSet(@PolyNonEmpty SortedSet s) { + public static @Unmodifiable @PolyNonEmpty SortedSet unmodifiableSortedSet(@MaybeModifiable @PolyNonEmpty SortedSet s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSortedSet.class) { return s; @@ -1497,7 +1498,7 @@ public SortedSet tailSet(E fromElement) { * @return an unmodifiable view of the specified navigable set * @since 1.8 */ - public static @Unmodifiable @PolyNonEmpty NavigableSet unmodifiableNavigableSet(@PolyNonEmpty NavigableSet s) { + public static @Unmodifiable @PolyNonEmpty NavigableSet unmodifiableNavigableSet(@MaybeModifiable @PolyNonEmpty NavigableSet s) { if (s.getClass() == UnmodifiableNavigableSet.class) { return s; } @@ -1610,7 +1611,7 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @return an unmodifiable view of the specified list. */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty List unmodifiableList(@PolyGrowShrink @PolyNonEmpty List list) { + public static @Unmodifiable @PolyGrowShrink @PolyNonEmpty List unmodifiableList(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty List list) { if (list.getClass() == UnmodifiableList.class || list.getClass() == UnmodifiableRandomAccessList.class) { return (List) list; } @@ -1801,7 +1802,7 @@ private Object writeReplace() { * @return an unmodifiable view of the specified map. */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyNonEmpty Map unmodifiableMap(@PolyNonEmpty Map m) { + public static @Unmodifiable @PolyNonEmpty Map unmodifiableMap(@MaybeModifiable @PolyNonEmpty Map m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableMap.class) { return (Map) m; @@ -2284,7 +2285,7 @@ public V putLast(K k, V v) { * @return an unmodifiable view of the specified sorted map. */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyNonEmpty SortedMap unmodifiableSortedMap(@PolyNonEmpty SortedMap m) { + public static @Unmodifiable @PolyNonEmpty SortedMap unmodifiableSortedMap(@MaybeModifiable @PolyNonEmpty SortedMap m) { // Not checking for subclasses because of heap pollution and information leakage. if (m.getClass() == UnmodifiableSortedMap.class) { return (SortedMap) m; @@ -2340,7 +2341,7 @@ public SortedMap tailMap(K fromKey) * @since 1.8 */ @SuppressWarnings("unchecked") - public static @Unmodifiable @PolyNonEmpty NavigableMap unmodifiableNavigableMap(@PolyNonEmpty NavigableMap m) { + public static @Unmodifiable @PolyNonEmpty NavigableMap unmodifiableNavigableMap(@MaybeModifiable @PolyNonEmpty NavigableMap m) { if (m.getClass() == UnmodifiableNavigableMap.class) { return (NavigableMap) m; } @@ -6386,7 +6387,7 @@ static boolean eq(Object o1, Object o2) { * @throws NullPointerException if {@code c} is null * @since 1.5 */ - public static @NonNegative int frequency(Collection c, @Nullable Object o) { + public static @NonNegative int frequency(@MaybeModifiable Collection c, @Nullable Object o) { int result = 0; if (o == null) { for (Object e : c) @@ -6438,7 +6439,7 @@ static boolean eq(Object o1, Object o2) { * (optional) * @since 1.5 */ - public static boolean disjoint(Collection c1, Collection c2) { + public static boolean disjoint(@MaybeModifiable Collection c1, @MaybeModifiable Collection c2) { // The collection to be used for contains(). Preference is given to // the collection who's contains() has lower O() complexity. Collection contains = c2; diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 6226d56444b9..e2e56d733575 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 0ee14ae1795f..5d00823e2713 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 58cc8d682977..b0cd7488430c 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 463bbb37c970..1d97736cfd09 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -35,6 +35,7 @@ import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -181,7 +182,7 @@ public interface List extends SequencedCollection { * @return the number of elements in this list */ @Pure - @NonNegative int size(@GuardSatisfied List this); + @NonNegative int size(@MaybeModifiable @GuardSatisfied List this); /** * Returns {@code true} if this list contains no elements. @@ -190,7 +191,7 @@ public interface List extends SequencedCollection { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied List this); + boolean isEmpty(@MaybeModifiable @GuardSatisfied List this); /** * Returns {@code true} if this list contains the specified element. @@ -209,7 +210,7 @@ public interface List extends SequencedCollection { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@GuardSatisfied List this, @UnknownSignedness Object o); + boolean contains(@MaybeModifiable @GuardSatisfied List this, @UnknownSignedness Object o); /** * Returns an iterator over the elements in this list in proper sequence. @@ -217,7 +218,7 @@ public interface List extends SequencedCollection { * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty List this); + @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); /** * Returns an array containing all of the elements in this list in proper @@ -236,7 +237,7 @@ public interface List extends SequencedCollection { * @see Arrays#asList(Object[]) */ @SideEffectFree - @PolyNull @PolySigned Object[] toArray(List<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(@MaybeModifiable List<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this list in @@ -277,7 +278,8 @@ public interface List extends SequencedCollection { * this list * @throws NullPointerException if the specified array is null */ - @Nullable T[] toArray(List this, @PolyNull T[] a); + @SideEffectFree + @Nullable T[] toArray(@MaybeModifiable List this, @PolyNull T[] a); // Modification Operations @@ -356,7 +358,7 @@ public interface List extends SequencedCollection { * @see #contains(Object) */ @Pure - boolean containsAll(@GuardSatisfied List this, Collection c); + boolean containsAll(@MaybeModifiable @GuardSatisfied List this, Collection c); /** * Appends all of the elements in the specified collection to the end of @@ -601,7 +603,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this, @Nullable Object o); + boolean equals(@MaybeModifiable @GuardSatisfied List this, @Nullable Object o); /** * Returns the hash code value for this list. The hash code of a list @@ -621,7 +623,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this); + int hashCode(@MaybeModifiable @GuardSatisfied List this); // Positional Access Operations @@ -635,7 +637,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator= size()}) */ @Pure - E get(@GuardSatisfied List this, @IndexFor({"this"}) int index); + E get(@MaybeModifiable @GuardSatisfied List this, @IndexFor({"this"}) int index); /** * Replaces the element at the specified position in this list with the @@ -723,7 +725,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparatoroptional) */ @Pure - @GTENegativeOne int indexOf(@GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); + @GTENegativeOne int indexOf(@MaybeModifiable @GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns the index of the last occurrence of the specified element @@ -743,7 +745,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparatoroptional) */ @Pure - @GTENegativeOne int lastIndexOf(@GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); + @GTENegativeOne int lastIndexOf(@MaybeModifiable @GuardSatisfied List this, @GuardSatisfied @UnknownSignedness Object o); // List Iterators @@ -755,7 +757,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator listIterator(@PolyGrowShrink @PolyNonEmpty List this); + @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); /** * Returns a list iterator over the elements in this list (in proper @@ -772,7 +774,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator size()}) */ - @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); + @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); // View @@ -1286,7 +1288,7 @@ default List reversed() { * @since 10 */ @SideEffectFree - static @Unmodifiable @PolyNonEmpty List copyOf(@PolyNonEmpty Collection coll) { + static @Unmodifiable @PolyNonEmpty List copyOf(@MaybeModifiable @PolyNonEmpty Collection coll) { return ImmutableCollections.listCopy(coll); } } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 591c8478294b..4ea0da0de19a 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -204,7 +205,7 @@ public interface Map { * @return the number of key-value mappings in this map */ @Pure - @NonNegative int size(@GuardSatisfied Map this); + @NonNegative int size(@MaybeModifiable @GuardSatisfied Map this); /** * Returns {@code true} if this map contains no key-value mappings. @@ -213,7 +214,7 @@ public interface Map { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied Map this); + boolean isEmpty(@MaybeModifiable @GuardSatisfied Map this); /** * Returns {@code true} if this map contains a mapping for the specified @@ -234,7 +235,7 @@ public interface Map { @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure @EnsuresNonEmptyIf(result=true, expression={"this"}) - boolean containsKey(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); + boolean containsKey(@MaybeModifiable @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); /** * Returns {@code true} if this map maps one or more keys to the @@ -254,7 +255,7 @@ public interface Map { */ @Pure @EnsuresNonEmptyIf(result=true, expression={"this"}) - boolean containsValue(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); + boolean containsValue(@MaybeModifiable @GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); /** * Returns the value to which the specified key is mapped, @@ -281,7 +282,7 @@ public interface Map { * does not permit null keys ({@linkplain Collection##optional-restrictions optional}) */ @Pure - @Nullable V get(@GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); + @Nullable V get(@MaybeModifiable @GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); // Modification Operations @@ -511,7 +512,7 @@ interface Entry { * removed from the backing map. */ @Pure - K getKey(Map.@GuardSatisfied Entry this); + K getKey(Map.@MaybeModifiable @GuardSatisfied Entry this); /** * Returns the value corresponding to this entry. If the mapping @@ -524,7 +525,7 @@ interface Entry { * removed from the backing map. */ @Pure - V getValue(Map.@GuardSatisfied Entry this); + V getValue(Map.@MaybeModifiable @GuardSatisfied Entry this); /** * Replaces the value corresponding to this entry with the specified @@ -568,7 +569,7 @@ interface Entry { * entry */ @Pure - boolean equals(Map.@GuardSatisfied Entry this, @GuardSatisfied @Nullable Object o); + boolean equals(Map.@MaybeModifiable @GuardSatisfied Entry this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this map entry. The hash code @@ -587,7 +588,7 @@ interface Entry { * @see #equals(Object) */ @Pure - int hashCode(Map.@GuardSatisfied Entry this); + int hashCode(Map.@MaybeModifiable @GuardSatisfied Entry this); /** * Returns a comparator that compares {@link Map.Entry} in natural order on key. @@ -688,8 +689,7 @@ public static Comparator> comparingByValue(Comparator - Map.@Unmodifiable Entry copyOf(Map.Entry e) { + public static Map.@Unmodifiable Entry copyOf(Map.@MaybeModifiable Entry e) { Objects.requireNonNull(e); if (e instanceof KeyValueHolder) { return (Map.Entry) e; @@ -714,7 +714,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @Nullable Object o); + boolean equals(@MaybeModifiable @GuardSatisfied Map this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this map. The hash code of a map is @@ -730,7 +730,7 @@ public static Comparator> comparingByValue(Comparator this); + int hashCode(@MaybeModifiable @GuardSatisfied Map this); // Defaultable methods @@ -1831,7 +1831,7 @@ default boolean replace(@Replaceable Map this, K key, V oldValue, V newVal */ @SuppressWarnings({"rawtypes","unchecked"}) @SideEffectFree - static @Unmodifiable @PolyNonEmpty Map copyOf(@PolyNonEmpty Map map) { + static @Unmodifiable @PolyNonEmpty Map copyOf(@MaybeModifiable @PolyNonEmpty Map map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map)map; } else if (map.isEmpty()) { // Implicit nullcheck of map diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index b55c022a766f..2e6095c586f7 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; @@ -146,7 +147,7 @@ public interface Set extends Collection { * @return the number of elements in this set (its cardinality) */ @Pure - @NonNegative int size(@GuardSatisfied Set this); + @NonNegative int size(@MaybeModifiable @GuardSatisfied Set this); /** * Returns {@code true} if this set contains no elements. @@ -155,7 +156,7 @@ public interface Set extends Collection { */ @Pure @EnsuresNonEmptyIf(result = false, expression = "this") - boolean isEmpty(@GuardSatisfied Set this); + boolean isEmpty(@MaybeModifiable @GuardSatisfied Set this); /** * Returns {@code true} if this set contains the specified element. @@ -174,7 +175,7 @@ public interface Set extends Collection { */ @Pure @EnsuresNonEmptyIf(result = true, expression = "this") - boolean contains(@GuardSatisfied Set this, @GuardSatisfied @UnknownSignedness Object o); + boolean contains(@MaybeModifiable @GuardSatisfied Set this, @GuardSatisfied @UnknownSignedness Object o); /** * Returns an iterator over the elements in this set. The elements are @@ -184,7 +185,7 @@ public interface Set extends Collection { * @return an iterator over the elements in this set */ @SideEffectFree - @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty Set this); + @MaybeModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Set this); /** * Returns an array containing all of the elements in this set. @@ -203,7 +204,7 @@ public interface Set extends Collection { * @return an array containing all the elements in this set */ @SideEffectFree - @PolyNull @PolySigned Object[] toArray(Set<@PolyNull @PolySigned E> this); + @PolyNull @PolySigned Object[] toArray(@MaybeModifiable Set<@PolyNull @PolySigned E> this); /** * Returns an array containing all of the elements in this set; the @@ -247,7 +248,8 @@ public interface Set extends Collection { * set * @throws NullPointerException if the specified array is null */ - @Nullable T [] toArray(Set this, @PolyNull T[] a); + @SideEffectFree + @Nullable T [] toArray(@MaybeModifiable Set this, @PolyNull T[] a); // Modification Operations @@ -336,7 +338,7 @@ public interface Set extends Collection { * @see #contains(Object) */ @Pure - boolean containsAll(@GuardSatisfied Set this, @GuardSatisfied Collection c); + boolean containsAll(@MaybeModifiable @GuardSatisfied Set this, @GuardSatisfied Collection c); /** * Adds all of the elements in the specified collection to this set if @@ -442,7 +444,7 @@ public interface Set extends Collection { * @return {@code true} if the specified object is equal to this set */ @Pure - boolean equals(@GuardSatisfied Set this, @GuardSatisfied @Nullable Object o); + boolean equals(@MaybeModifiable @GuardSatisfied Set this, @GuardSatisfied @Nullable Object o); /** * Returns the hash code value for this set. The hash code of a set is @@ -458,7 +460,7 @@ public interface Set extends Collection { * @see Set#equals(Object) */ @Pure - int hashCode(@GuardSatisfied Set this); + int hashCode(@MaybeModifiable @GuardSatisfied Set this); /** * Creates a {@code Spliterator} over the elements in this set. @@ -486,7 +488,7 @@ public interface Set extends Collection { @Override @SideEffectFree @DoesNotUnrefineReceiver("modifiability") - default Spliterator spliterator(Set this) { + default Spliterator spliterator(@MaybeModifiable Set this) { return Spliterators.spliterator(this, Spliterator.DISTINCT); } @@ -787,7 +789,7 @@ default Spliterator spliterator(Set this) { */ @SuppressWarnings("unchecked") @SideEffectFree - static @Unmodifiable @PolyNonEmpty Set copyOf(@PolyNonEmpty Collection coll) { + static @Unmodifiable @PolyNonEmpty Set copyOf(@MaybeModifiable @PolyNonEmpty Collection coll) { if (coll instanceof ImmutableCollections.AbstractImmutableSet) { return (Set)coll; } else if (coll.isEmpty()) { // Implicit nullcheck of coll diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index b16ac786a200..0b282df21623 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4710,7 +4710,7 @@ public final boolean retainAll(Collection extends CollectionView + public static final @Modifiable class KeySetView extends CollectionView implements Set, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; @SuppressWarnings("serial") // Conditionally serializable @@ -5391,6 +5391,7 @@ static final class SearchKeysTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final Function searchFunction; @@ -5435,6 +5436,7 @@ static final class SearchValuesTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final Function searchFunction; @@ -5479,6 +5481,7 @@ static final class SearchEntriesTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final Function, ? extends U> searchFunction; @@ -5523,6 +5526,7 @@ static final class SearchMappingsTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final BiFunction searchFunction; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 7a7d1390f754..25da842e2671 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -36,6 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -98,7 +99,7 @@ public interface ConcurrentMap this,Object key, V defaultValue) { + default V getOrDefault(@MaybeModifiable ConcurrentMap this,Object key, V defaultValue) { V v; return ((v = get(key)) != null) ? v : defaultValue; } @@ -123,7 +124,7 @@ default V getOrDefault(ConcurrentMap this,Object key, V defaultValue) { */ @Override @DoesNotUnrefineReceiver("modifiability") - default void forEach(ConcurrentMap this,BiConsumer action) { + default void forEach(@MaybeModifiable ConcurrentMap this,BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { K k; diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index f7f00e4f177f..38e0ba4ba03a 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -1281,7 +1281,7 @@ public boolean add(@Growable LinkedTransferQueue this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { + public boolean tryTransfer(@GuardSatisfied @Growable @CanShrink LinkedTransferQueue this, E e) { return xfer(e, true, NOW, 0L) == null; } @@ -1298,7 +1298,7 @@ public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQu */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { + public void transfer(@GuardSatisfied @Growable @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { if (xfer(e, true, SYNC, 0L) != null) { Thread.interrupted(); // failure possible only due to interrupt throw new InterruptedException(); @@ -1321,7 +1321,8 @@ public void transfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean tryTransfer(@Growable @GuardSatisfied @CanShrink LinkedTransferQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { + public boolean tryTransfer(@GuardSatisfied @Growable @CanShrink LinkedTransferQueue this, E e, long timeout, TimeUnit unit) + throws InterruptedException { if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null) return true; if (!Thread.interrupted()) @@ -1350,7 +1351,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { + public E poll(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this) { return xfer(null, false, NOW, 0L); } @@ -1360,7 +1361,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1376,7 +1377,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1624,14 +1625,14 @@ public boolean removeAll(@Shrinkable @CanShrink LinkedTransferQueue this, Col */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { + public boolean retainAll(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) { + public void clear(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this) { bulkRemove(e -> true); } diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index c9871800c108..4dc4f8077c49 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -875,7 +875,8 @@ public void put(@Growable SynchronousQueue this, E e) throws InterruptedExcep */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offer(@Growable SynchronousQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { + public boolean offer(@Growable SynchronousQueue this, E e, long timeout, TimeUnit unit) + throws InterruptedException { if (e == null) throw new NullPointerException(); if (transferer.transfer(e, true, unit.toNanos(timeout)) != null) return true; @@ -909,7 +910,7 @@ public boolean offer(@Growable SynchronousQueue this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { + public E take(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this) throws InterruptedException { E e = transferer.transfer(null, false, 0); if (e != null) return e; @@ -928,7 +929,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) t */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public E poll(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = transferer.transfer(null, true, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) return e; @@ -944,7 +945,7 @@ public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, l */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { + public E poll(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this) { return transferer.transfer(null, true, 0); } @@ -987,7 +988,7 @@ public int remainingCapacity() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this) { + public void clear(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this) { } /** @@ -1050,7 +1051,7 @@ public boolean removeAll(@Shrinkable @CanShrink SynchronousQueue this, Collec */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, Collection c) { + public boolean retainAll(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this, Collection c) { return false; } @@ -1129,7 +1130,7 @@ public String toString() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c) { + public int drainTo(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this, @Growable Collection c) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); @@ -1147,7 +1148,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue th */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public int drainTo(@Shrinkable @GuardSatisfied @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { + public int drainTo(@GuardSatisfied @Shrinkable @CanShrink SynchronousQueue this, @Growable Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) throw new IllegalArgumentException(); From fe7708a5830cefb670b12923c58c1fee2e6c8a60 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 27 May 2026 10:50:12 -0700 Subject: [PATCH 094/119] Put `@GuardSatisfied` first --- .../classes/java/util/concurrent/LinkedTransferQueue.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 38e0ba4ba03a..49a1bbbc0ffe 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -1332,7 +1332,7 @@ public boolean tryTransfer(@GuardSatisfied @Growable @CanShrink LinkedTransferQu // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { + public E take(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this) throws InterruptedException { E e = xfer(null, false, SYNC, 0L); if (e != null) return e; @@ -1342,7 +1342,7 @@ public E take(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E poll(@Shrinkable @GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { + public E poll(@GuardSatisfied @Shrinkable @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { E e = xfer(null, false, TIMED, unit.toNanos(timeout)); if (e != null || !Thread.interrupted()) return e; From 5cea093e396ea89baa50476890b92cb5847cde51 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 27 May 2026 14:39:16 -0700 Subject: [PATCH 095/119] Add safe directory --- .github/workflows/ci.yml | 60 +++++++++++++++++++++++++++++++++++++++ .github/workflows/defs.m4 | 9 ++++++ 2 files changed, 69 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f01059b7ea2c..8b96933014cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,6 +153,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -170,6 +173,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -187,6 +193,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -204,6 +213,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -221,6 +233,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -238,6 +253,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -255,6 +273,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -272,6 +293,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -289,6 +313,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -306,6 +333,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -323,6 +353,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -340,6 +373,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -357,6 +393,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -374,6 +413,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -391,6 +433,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -408,6 +453,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -426,6 +474,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -443,6 +494,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -460,6 +514,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -477,6 +534,9 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework diff --git a/.github/workflows/defs.m4 b/.github/workflows/defs.m4 index a1be27425770..c7dd3ff561df 100644 --- a/.github/workflows/defs.m4 +++ b/.github/workflows/defs.m4 @@ -23,6 +23,9 @@ define([cftests_job], [dnl uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -42,6 +45,9 @@ define([daikon_job], [dnl uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework @@ -60,6 +66,9 @@ define([plume_lib_job], [dnl uses: actions/checkout@v6 with: fetch-depth: 25 + - name: git config + run: | + git config --global --add safe.directory /__w/jdk/jdk - name: clone git-scripts run: mkdir -p /tmp/$USER && git -C /tmp/$USER clone --depth=1 -q https://github.com/plume-lib/git-scripts.git - name: clone checker-framework From 93a7c630da32d2de465d488eeffdb721c4149f46 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 27 May 2026 16:22:21 -0700 Subject: [PATCH 096/119] removed @PolyModifiable on list.iterators. --- src/java.base/share/classes/java/util/AbstractList.java | 6 +++--- .../share/classes/java/util/AbstractSequentialList.java | 4 ++-- src/java.base/share/classes/java/util/List.java | 6 +++--- .../classes/java/util/concurrent/ConcurrentHashMap.java | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index ddcb01da7045..bb92da589247 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -348,7 +348,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) { + public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) { return new Itr(); } @@ -360,7 +360,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * * @see #listIterator(int) */ - public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this) { + public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this) { return listIterator(0); } @@ -387,7 +387,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHi * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractList this, final @IndexOrHigh({"this"}) int index) { + public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this, final @IndexOrHigh({"this"}) int index) { rangeCheckForAdd(index); return new ListItr(index); diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 5dd09a930be1..750d0de9b2ce 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -268,7 +268,7 @@ public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequent * @return an iterator over the elements in this list (in proper sequence) */ @SideEffectFree - public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty AbstractSequentialList this) { + public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty AbstractSequentialList this) { return listIterator(); } @@ -282,5 +282,5 @@ public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequent * sequence) * @throws IndexOutOfBoundsException {@inheritDoc} */ - public abstract @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable AbstractSequentialList this, int index); + public abstract @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink AbstractSequentialList this, int index); } diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 1d97736cfd09..e0faf2f7f340 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -218,7 +218,7 @@ public interface List extends SequencedCollection { * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); + @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty List this); /** * Returns an array containing all of the elements in this list in proper @@ -757,7 +757,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this); + @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this); /** * Returns a list iterator over the elements in this list (in proper @@ -774,7 +774,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator size()}) */ - @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); + @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty List this, @IndexOrHigh({"this"}) int index); // View diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 0b282df21623..5e565d20aa2e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4710,7 +4710,7 @@ public final boolean retainAll(Collection extends CollectionView + public static final class KeySetView extends CollectionView implements Set, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; @SuppressWarnings("serial") // Conditionally serializable From a4c6fc623f6ab40808f864354dba0fb3e6e68159 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 27 May 2026 17:20:08 -0700 Subject: [PATCH 097/119] fixed toArray annotation in AbstractCollection.java --- src/java.base/share/classes/java/util/AbstractCollection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 68cc5df6677b..0c7375469f9f 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -214,7 +214,7 @@ public boolean contains(@MaybeModifiable @GuardSatisfied AbstractCollection t * @throws NullPointerException {@inheritDoc} */ @SuppressWarnings("unchecked") - public @Nullable T [] toArray(@MaybeModifiable @PolyNull T [] a) { + public @Nullable T [] toArray(@MaybeModifiable AbstractCollection this, @PolyNull T [] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : From 338c6a39fc9ee5c299e28dbde20d93a3c99a4a2a Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Fri, 29 May 2026 09:31:29 -0700 Subject: [PATCH 098/119] Rename qualifiers --- checker-qual.jar | Bin 291748 -> 291812 bytes .../classes/java/util/AbstractCollection.java | 10 ++-- .../share/classes/java/util/AbstractList.java | 4 +- .../share/classes/java/util/AbstractMap.java | 8 +-- .../java/util/AbstractSequentialList.java | 10 ++-- .../share/classes/java/util/AbstractSet.java | 4 +- .../share/classes/java/util/ArrayDeque.java | 10 ++-- .../share/classes/java/util/ArrayList.java | 10 ++-- .../share/classes/java/util/Collection.java | 4 +- .../share/classes/java/util/Collections.java | 52 +++++++++--------- .../share/classes/java/util/EnumMap.java | 8 +-- .../share/classes/java/util/EnumSet.java | 30 +++++----- .../share/classes/java/util/HashMap.java | 8 +-- .../share/classes/java/util/HashSet.java | 14 ++--- .../share/classes/java/util/Hashtable.java | 8 +-- .../classes/java/util/IdentityHashMap.java | 8 +-- .../classes/java/util/LinkedHashMap.java | 14 ++--- .../classes/java/util/LinkedHashSet.java | 10 ++-- .../share/classes/java/util/LinkedList.java | 8 +-- .../share/classes/java/util/List.java | 6 +- .../share/classes/java/util/Map.java | 8 +-- .../share/classes/java/util/NavigableMap.java | 6 +- .../classes/java/util/PriorityQueue.java | 16 +++--- .../share/classes/java/util/Properties.java | 8 +-- .../java/util/ReverseOrderSortedMapView.java | 10 ++-- .../java/util/SequencedCollection.java | 6 +- .../share/classes/java/util/SortedMap.java | 8 +-- .../share/classes/java/util/Stack.java | 4 +- .../share/classes/java/util/TreeMap.java | 22 ++++---- .../share/classes/java/util/TreeSet.java | 14 ++--- .../share/classes/java/util/Vector.java | 12 ++-- .../share/classes/java/util/WeakHashMap.java | 8 +-- .../util/concurrent/ArrayBlockingQueue.java | 8 +-- .../util/concurrent/ConcurrentHashMap.java | 10 ++-- .../concurrent/ConcurrentLinkedDeque.java | 6 +- .../concurrent/ConcurrentLinkedQueue.java | 6 +- .../concurrent/ConcurrentNavigableMap.java | 8 +-- .../concurrent/ConcurrentSkipListMap.java | 22 ++++---- .../concurrent/ConcurrentSkipListSet.java | 14 ++--- .../java/util/concurrent/DelayQueue.java | 6 +- .../util/concurrent/LinkedBlockingDeque.java | 8 +-- .../util/concurrent/LinkedBlockingQueue.java | 8 +-- .../util/concurrent/LinkedTransferQueue.java | 6 +- .../concurrent/PriorityBlockingQueue.java | 10 ++-- .../checker/modifiability/qual/Growable.java | 2 +- ...lyMod.java => IteratorPolyShrinkable.java} | 8 +-- .../modifiability/qual/MaybeGrowable.java | 5 +- ....java => MaybeIteratorPolyShrinkable.java} | 6 +- .../modifiability/qual/MaybeReplaceable.java | 6 +- .../modifiability/qual/MaybeShrinkable.java | 7 ++- .../modifiability/qual/Modifiable.java | 4 +- .../modifiability/qual/PolyModifiable.java | 10 ++-- .../modifiability/qual/Replaceable.java | 2 +- .../modifiability/qual/Shrinkable.java | 4 +- .../modifiability/qual/UnmodifiableParam.java | 12 ++-- .../modifiability/qual/Unshrinkable.java | 4 +- .../dataflow/qual/SideEffectFree.java | 4 +- 57 files changed, 268 insertions(+), 266 deletions(-) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{IteratorPolyMod.java => IteratorPolyShrinkable.java} (71%) rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{MaybeIteratorPolyMod.java => MaybeIteratorPolyShrinkable.java} (83%) diff --git a/checker-qual.jar b/checker-qual.jar index 92ec2c9758ac4af63571c4096a6db5ad6ebef102..fbd435a517ff42057757a020a1a2d8e808d055b8 100644 GIT binary patch delta 12086 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 diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 0c7375469f9f..f90a0ef7df37 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -310,7 +310,7 @@ public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) { @@ -407,7 +407,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Coll */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean removeAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -444,7 +444,7 @@ public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean retainAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -475,7 +475,7 @@ public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { + public void clear(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { it.next(); diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index bb92da589247..fb178cdb4dd8 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -663,7 +663,7 @@ public int hashCode(@MaybeModifiable @GuardSatisfied AbstractList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + protected void removeRange(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i this) { * method will not all return the same set. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied AbstractMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { @@ -469,7 +469,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied AbstractMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { @@ -527,7 +527,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - public abstract @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); + public abstract @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 750d0de9b2ce..9eb9c7645f84 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -136,7 +136,7 @@ public E get(@MaybeModifiable @GuardSatisfied AbstractSequentialList this, in @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@IteratorPolyMod @Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public E set(@IteratorPolyShrinkable @Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { ListIterator e = listIterator(index); E oldVal = e.next(); @@ -170,7 +170,7 @@ public E set(@IteratorPolyMod @Replaceable @GuardSatisfied AbstractSequentialLis @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public void add(@IteratorPolyShrinkable @Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { listIterator(index).add(element); } catch (NoSuchElementException exc) { @@ -197,7 +197,7 @@ public void add(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialLis */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { + public E remove(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { try { ListIterator e = listIterator(index); E outCast = e.next(); @@ -242,7 +242,7 @@ public E remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Abstract */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { + public boolean addAll(@IteratorPolyShrinkable @Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { try { boolean modified = false; ListIterator e1 = listIterator(index); diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index fa3f8e9e2d48..c28ed04cc7b3 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -180,7 +180,7 @@ public int hashCode(@MaybeModifiable @GuardSatisfied AbstractSet this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { + public boolean removeAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index df6f3a597294..444c9c041a1f 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -203,7 +203,7 @@ private int newCapacity(int needed, int jump) { * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */ - public @Modifiable @IteratorPolyMod ArrayDeque() { + public @Modifiable @IteratorPolyShrinkable ArrayDeque() { elements = new Object[16 + 1]; } @@ -213,7 +213,7 @@ private int newCapacity(int needed, int jump) { * * @param numElements lower bound on initial capacity of the deque */ - public @Modifiable @IteratorPolyMod ArrayDeque(@NonNegative int numElements) { + public @Modifiable @IteratorPolyShrinkable ArrayDeque(@NonNegative int numElements) { elements = new Object[(numElements < 1) ? 1 : (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : @@ -230,7 +230,7 @@ private int newCapacity(int needed, int jump) { * @param c the collection whose elements are to be placed into the deque * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { this(c.size()); copyElements(c); } @@ -1245,7 +1245,7 @@ private T[] toArray(Class klazz) { * @return a copy of this deque */ @SideEffectFree - public @Modifiable @IteratorPolyMod ArrayDeque clone(@GuardSatisfied ArrayDeque this) { + public @Modifiable @IteratorPolyShrinkable ArrayDeque clone(@GuardSatisfied ArrayDeque this) { try { @SuppressWarnings("unchecked") ArrayDeque result = (ArrayDeque) super.clone(); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index dd0a291b1960..415fa480cc2d 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -183,7 +183,7 @@ public class ArrayList extends AbstractList * is negative */ @SideEffectFree - public @Modifiable @IteratorPolyMod ArrayList(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyShrinkable ArrayList(@NonNegative int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { @@ -198,7 +198,7 @@ public class ArrayList extends AbstractList * Constructs an empty list with an initial capacity of ten. */ @SideEffectFree - public @Modifiable @IteratorPolyMod ArrayList() { + public @Modifiable @IteratorPolyShrinkable ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } @@ -211,7 +211,7 @@ public class ArrayList extends AbstractList * @throws NullPointerException if the specified collection is null */ @SideEffectFree - public @Modifiable @IteratorPolyMod @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { @@ -385,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied ArrayList this) { + public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 0e80771451f7..29850ff68fb0 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -626,7 +626,7 @@ default T[] toArray(@MaybeModifiable Collection this, IntFunction ge */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { + default boolean removeIf(@IteratorPolyShrinkable @Shrinkable @CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 1426e5d2cd0b..93befcbef31d 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -178,7 +178,7 @@ private Collections() { */ @SuppressWarnings("unchecked") // @SideEffectsOnly("#1") - public static > void sort(@IteratorPolyMod @Replaceable List list) { + public static > void sort(@IteratorPolyShrinkable @Replaceable List list) { list.sort(null); } @@ -213,7 +213,7 @@ public static > void sort(@IteratorPolyMod @Repl */ @SuppressWarnings({"unchecked", "rawtypes"}) // @SideEffectsOnly("#1") - public static void sort(@IteratorPolyMod @Replaceable List list, @Nullable Comparator c) { + public static void sort(@IteratorPolyShrinkable @Replaceable List list, @Nullable Comparator c) { list.sort(c); } @@ -420,7 +420,7 @@ else if (cmp > 0) * @see List#reversed List.reversed */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void reverse(@IteratorPolyMod @Replaceable @GuardSatisfied List list) { + public static void reverse(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the {@code set} operation. */ - public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List list) { + public static void shuffle(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); // harmless race. @@ -490,7 +490,7 @@ public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void shuffle(@IteratorPolyMod @Replaceable List list, Random rnd) { + public static void shuffle(@IteratorPolyShrinkable @Replaceable List list, Random rnd) { shuffle(list, (RandomGenerator) rnd); } @@ -519,7 +519,7 @@ public static void shuffle(@IteratorPolyMod @Replaceable List list, Random rn * @since 21 */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List list, RandomGenerator rnd) { + public static void shuffle(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list, RandomGenerator rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) @@ -586,7 +586,7 @@ private static void swap(Object[] arr, int i, int j) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void fill(@IteratorPolyMod @Replaceable @GuardSatisfied List list, T obj) { + public static void fill(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list, T obj) { int size = list.size(); if (size < FILL_THRESHOLD || list instanceof RandomAccess) { @@ -619,7 +619,7 @@ public static void fill(@IteratorPolyMod @Replaceable @GuardSatisfied List void copy(@IteratorPolyMod @Replaceable List dest, @MaybeModifiable List src) { + public static void copy(@IteratorPolyShrinkable @Replaceable List dest, @MaybeModifiable List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -847,7 +847,7 @@ public static T max(@MaybeModifiable Collection coll, @Nullable * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static void rotate(@IteratorPolyMod @Replaceable @GuardSatisfied List list, int distance) { + public static void rotate(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list, int distance) { if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) rotate1(list, distance); else @@ -913,7 +913,7 @@ private static void rotate2(List list, int distance) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, @Nullable T oldVal, T newVal) { + public static boolean replaceAll(@IteratorPolyShrinkable @Replaceable List list, @Nullable T oldVal, T newVal) { boolean result = false; int size = list.size(); if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { @@ -1094,7 +1094,7 @@ public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, */ @SuppressWarnings("unchecked") @SideEffectFree - public static @IteratorPolyMod @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { + public static @IteratorPolyShrinkable @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { if (c.getClass() == UnmodifiableCollection.class) { return (Collection) c; } @@ -1340,7 +1340,7 @@ public E removeLast() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @IteratorPolyMod @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@MaybeModifiable @PolyNonEmpty Set s) { + public static @IteratorPolyShrinkable @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@MaybeModifiable @PolyNonEmpty Set s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSet.class) { return (Set) s; @@ -3226,7 +3226,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable SynchronizedMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable SynchronizedMap this) { synchronized (mutex) { if (keySet==null) keySet = new SynchronizedSet<>(m.keySet(), mutex); @@ -3235,7 +3235,7 @@ public void clear() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { synchronized (mutex) { if (entrySet==null) entrySet = new SynchronizedSet<>(m.entrySet(), mutex); @@ -3243,7 +3243,7 @@ public void clear() { } } - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SynchronizedMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SynchronizedMap this) { synchronized (mutex) { if (values==null) values = new SynchronizedCollection<>(m.values(), mutex); @@ -3552,19 +3552,19 @@ public NavigableMap descendingMap() { } } - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SynchronizedNavigableMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SynchronizedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SynchronizedNavigableMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable SynchronizedNavigableMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } @@ -4394,8 +4394,8 @@ private String badValueMsg(Object value) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable CheckedMap this) { return m.keySet(); } - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable CheckedMap this) { return m.values(); } + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable CheckedMap this) { return m.keySet(); } + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable CheckedMap this) { return m.values(); } @Pure public boolean equals(Object o) { return o == this || m.equals(o); } @Pure @@ -4436,7 +4436,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); return entrySet; @@ -4966,17 +4966,17 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable CheckedNavigableMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable CheckedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable CheckedNavigableMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable CheckedNavigableMap this) { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable CheckedNavigableMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable CheckedNavigableMap this) { return checkedNavigableSet(nm.descendingKeySet(), keyType); } @@ -6358,7 +6358,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) { * @see Enumeration * @see ArrayList */ - public static @Modifiable @IteratorPolyMod ArrayList list(Enumeration e) { + public static @Modifiable @IteratorPolyShrinkable ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 93bcc3f6da52..41fe09f88534 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -426,7 +426,7 @@ public void clear(@Shrinkable EnumMap this) { * @return a set view of the keys contained in this enum map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable EnumMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable EnumMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -474,7 +474,7 @@ public void clear(@Shrinkable KeySet this) { * @return a collection view of the values contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable EnumMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable EnumMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -528,7 +528,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index 5dedb0466f8e..86107f467b4b 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -105,7 +105,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ final transient Enum[] universe; - @Modifiable @IteratorPolyMod EnumSet(ClasselementType, Enum[] universe) { + @Modifiable @IteratorPolyShrinkable EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } @@ -119,7 +119,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An empty enum set of the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPolyMod EnumSet noneOf(Class elementType) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet noneOf(Class elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); @@ -140,7 +140,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An enum set containing all the elements in the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPolyMod EnumSet allOf(Class elementType) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet allOf(Class elementType) { EnumSet result = noneOf(elementType); result.addAll(); return result; @@ -163,7 +163,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code s} is null */ @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet copyOf(EnumSet s) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -182,7 +182,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code c} is null */ @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet copyOf(Collection c) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); } else { @@ -207,7 +207,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return The complement of the specified set in this set * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable @IteratorPolyMod EnumSet complementOf(EnumSet s) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet complementOf(EnumSet s) { EnumSet result = copyOf(s); result.complement(); return result; @@ -228,7 +228,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified element */ @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet of(E e) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); return result; @@ -250,7 +250,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -274,7 +274,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -300,7 +300,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3, E e4) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -327,7 +327,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3, E e4, + public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2, E e3, E e4, E e5) { EnumSet result = noneOf(e1.getDeclaringClass()); @@ -355,7 +355,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SafeVarargs @SideEffectFree - public static > @Modifiable @IteratorPolyMod EnumSet of(E first, E... rest) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) @@ -377,7 +377,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ - public static > @Modifiable @IteratorPolyMod EnumSet range(E from, E to) { + public static > @Modifiable @IteratorPolyShrinkable EnumSet range(E from, E to) { if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to); EnumSet result = noneOf(from.getDeclaringClass()); @@ -399,7 +399,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SuppressWarnings("unchecked") @SideEffectFree - public @Modifiable @IteratorPolyMod EnumSet clone() { + public @Modifiable @IteratorPolyShrinkable EnumSet clone() { try { return (EnumSet) super.clone(); } catch(CloneNotSupportedException e) { diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index e2e56d733575..37dd28cd9805 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -963,7 +963,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1103,7 +1103,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1170,7 +1170,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 5d00823e2713..7e2cbc161601 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -126,7 +126,7 @@ public class HashSet * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPolyMod HashSet() { + public @Modifiable @IteratorPolyShrinkable HashSet() { map = new HashMap<>(); } @@ -139,7 +139,7 @@ public class HashSet * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -157,7 +157,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPolyMod HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPolyShrinkable HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -173,7 +173,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPolyMod HashSet(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyShrinkable HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -190,7 +190,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @Modifiable @IteratorPolyMod HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable @IteratorPolyShrinkable HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } @@ -297,7 +297,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied HashSet this) { + public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied HashSet this) { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index cb7eaf080620..25d6cb5d38e6 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -710,7 +710,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied Hashtable this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); return keySet; @@ -759,7 +759,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); return entrySet; @@ -850,7 +850,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied Hashtable this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), this); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 13ad5906714e..14de6a36e83a 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1049,7 +1049,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1169,7 +1169,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1287,7 +1287,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 2dff6128f0f6..e0a284667e46 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -661,7 +661,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable LinkedHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable LinkedHashMap this) { return sequencedKeySet(); } @@ -828,7 +828,7 @@ public SequencedSet reversed() { * @return a view of the values contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable LinkedHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable LinkedHashMap this) { return sequencedValues(); } @@ -949,7 +949,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -1268,17 +1268,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReversedLinkedHashMapView this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReversedLinkedHashMapView this) { return base.sequencedKeySet().reversed(); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReversedLinkedHashMapView this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReversedLinkedHashMapView this) { return base.sequencedValues().reversed(); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index b0cd7488430c..0f2185dc6a6d 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -155,7 +155,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPolyMod LinkedHashSet(int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPolyShrinkable LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } @@ -171,7 +171,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPolyMod LinkedHashSet(int initialCapacity) { + public @Modifiable @IteratorPolyShrinkable LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } @@ -179,7 +179,7 @@ public class LinkedHashSet * Constructs a new, empty linked hash set with the default initial * capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPolyMod LinkedHashSet() { + public @Modifiable @IteratorPolyShrinkable LinkedHashSet() { super(16, .75f, true); } @@ -193,7 +193,7 @@ public class LinkedHashSet * this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyMod LinkedHashSet(Collection c) { + public @Modifiable @IteratorPolyShrinkable LinkedHashSet(Collection c) { super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true); addAll(c); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index f8ee1602669f..66412ec7c80d 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -144,7 +144,7 @@ void dataStructureInvariants() { /** * Constructs an empty list. */ - public @Modifiable @IteratorPolyMod LinkedList() { + public @Modifiable @IteratorPolyShrinkable LinkedList() { } /** @@ -155,7 +155,7 @@ void dataStructureInvariants() { * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -1149,7 +1149,7 @@ private LinkedList superClone() { * @return a shallow copy of this {@code LinkedList} instance */ @SideEffectFree - public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied LinkedList this) { + public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied LinkedList this) { LinkedList clone = superClone(); // Put clone into "virgin" state diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index e0faf2f7f340..06e3b0378b3a 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -34,7 +34,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -494,7 +494,7 @@ public interface List extends SequencedCollection { * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - default void replaceAll(@IteratorPolyMod @Replaceable List this, UnaryOperator operator) { + default void replaceAll(@IteratorPolyShrinkable @Replaceable List this, UnaryOperator operator) { Objects.requireNonNull(operator); final ListIterator li = this.listIterator(); while (li.hasNext()) { @@ -564,7 +564,7 @@ default void replaceAll(@IteratorPolyMod @Replaceable List this, UnaryOperato @SuppressWarnings({"unchecked", "rawtypes"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void sort(@IteratorPolyMod @Replaceable List this, Comparator c) { + default void sort(@IteratorPolyShrinkable @Replaceable List this, Comparator c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator i = this.listIterator(); diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 4ea0da0de19a..03a19c816ba2 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -404,7 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -422,7 +422,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Collection values(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable @PolyNonEmpty Collection values(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -441,7 +441,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 51d379b92838..256e88b9449a 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,7 +36,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -313,7 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable NavigableMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable NavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -330,7 +330,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable NavigableMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable NavigableMap this); /** * Returns a view of the portion of this map whose keys range from diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index b5c3777f9d18..031a0c01a81f 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -153,7 +153,7 @@ public class PriorityQueue extends AbstractQueue * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyMod PriorityQueue() { + public @Modifiable @IteratorPolyShrinkable PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -166,7 +166,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyMod PriorityQueue(@Positive int initialCapacity) { + public @Modifiable @IteratorPolyShrinkable PriorityQueue(@Positive int initialCapacity) { this(initialCapacity, null); } @@ -179,7 +179,7 @@ public class PriorityQueue extends AbstractQueue * natural ordering} of the elements will be used. * @since 1.8 */ - public @Modifiable @IteratorPolyMod PriorityQueue(Comparator comparator) { + public @Modifiable @IteratorPolyShrinkable PriorityQueue(Comparator comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); } @@ -194,7 +194,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 */ - public @Modifiable @IteratorPolyMod PriorityQueue(@Positive int initialCapacity, + public @Modifiable @IteratorPolyShrinkable PriorityQueue(@Positive int initialCapacity, Comparator comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility @@ -220,7 +220,7 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { if (c instanceof SortedSet) { SortedSet ss = (SortedSet) c; this.comparator = (Comparator) ss.comparator(); @@ -251,7 +251,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified priority queue or any * of its elements are null */ - public @Modifiable @IteratorPolyMod PriorityQueue(PriorityQueue c) { + public @Modifiable @IteratorPolyShrinkable PriorityQueue(PriorityQueue c) { this.comparator = (Comparator) c.comparator(); initFromPriorityQueue(c); } @@ -269,7 +269,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPolyMod PriorityQueue(SortedSet c) { + public @Modifiable @IteratorPolyShrinkable PriorityQueue(SortedSet c) { this.comparator = (Comparator) c.comparator(); initElementsFromCollection(c); } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 0d4b048197c7..7f51a735af03 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -27,7 +27,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1412,19 +1412,19 @@ public synchronized String toString() { @Override @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrinkable Properties this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrinkable Properties this) { return Collections.synchronizedSet(map.keySet(), this); } @Override @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable Properties this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable Properties this) { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Properties this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Properties this) { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index c7cf58a7393f..4dbf8608c87d 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -115,7 +115,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReverseOrderSortedMapView this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE @SideEffectFree @@ -130,7 +130,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReverseOrderSortedMapView this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReverseOrderSortedMapView this) { return new AbstractCollection<>() { // inherit add(), which throws UOE @SideEffectFree @@ -145,7 +145,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE @SideEffectFree @@ -438,7 +438,7 @@ public String toString() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Submap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Submap this) { return new AbstractSet<>() { @SideEffectFree public Iterator> iterator() { diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 2bfbc7336e52..8b28c96b2220 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -193,7 +193,7 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { + default E removeFirst(@IteratorPolyShrinkable @Shrinkable SequencedCollection this) { var it = this.iterator(); E e = it.next(); it.remove(); @@ -217,7 +217,7 @@ default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { + default E removeLast(@IteratorPolyShrinkable @Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); E e = it.next(); it.remove(); diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 5a7c0460749d..f313cc7706e1 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -265,7 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied SortedMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied SortedMap this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -286,7 +286,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied SortedMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied SortedMap this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -307,7 +307,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** * Throws {@code UnsupportedOperationException}. The encounter order induced by this diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index ab8c4b91a1da..ff0d9802863a 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -67,7 +67,7 @@ public class Stack extends Vector { /** * Creates an empty Stack. */ - public @Modifiable @IteratorPolyMod Stack() { + public @Modifiable @IteratorPolyShrinkable Stack() { } /** diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 7a81625ea84a..7d445e2fcbe7 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1199,7 +1199,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1207,7 +1207,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } @@ -1216,7 +1216,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1242,7 +1242,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1274,7 +1274,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } @@ -2109,19 +2109,19 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - public final @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable NavigableSubMap this) { + public final @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable NavigableSubMap this) { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } @SideEffectFree - public final @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable NavigableSubMap this) { + public final @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable NavigableSubMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable NavigableSubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable NavigableSubMap this) { return descendingMap().navigableKeySet(); } @@ -2466,7 +2466,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); } @@ -2560,7 +2560,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 0b5a0ab42538..ebf216c5f226 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -131,7 +131,7 @@ public class TreeSet extends AbstractSet /** * Constructs a set backed by the specified navigable map. */ - @Modifiable @IteratorPolyMod TreeSet(NavigableMap m) { + @Modifiable @IteratorPolyShrinkable TreeSet(NavigableMap m) { this.m = m; } @@ -148,7 +148,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable @IteratorPolyMod TreeSet() { + public @Modifiable @IteratorPolyShrinkable TreeSet() { this(new TreeMap<>()); } @@ -165,7 +165,7 @@ public class TreeSet extends AbstractSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyMod TreeSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyShrinkable TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -183,7 +183,7 @@ public class TreeSet extends AbstractSet * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -565,7 +565,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied TreeSet this) { + public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 40256d67eb7a..01287b8fdea8 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -167,7 +167,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPolyMod Vector(@NonNegative int initialCapacity, int capacityIncrement) { + public @Modifiable @IteratorPolyShrinkable Vector(@NonNegative int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ @@ -184,7 +184,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPolyMod Vector(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyShrinkable Vector(@NonNegative int initialCapacity) { this(initialCapacity, 0); } @@ -193,7 +193,7 @@ public class Vector * has size {@code 10} and its standard capacity increment is * zero. */ - public @Modifiable @IteratorPolyMod Vector() { + public @Modifiable @IteratorPolyShrinkable Vector() { this(10); } @@ -207,7 +207,7 @@ public class Vector * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); elementCount = a.length; if (c.getClass() == ArrayList.class) { @@ -721,7 +721,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @return a clone of this vector */ @SideEffectFree - public synchronized @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied Vector this) { + public synchronized @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied Vector this) { try { @SuppressWarnings("unchecked") Vector v = (Vector) super.clone(); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 64ffd9d6764f..fc77fa2b261e 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -935,7 +935,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -998,7 +998,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1051,7 +1051,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); } 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 fbdcfa6bd5ff..534500453a2c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -277,7 +277,7 @@ void removeAt(final int removeIndex) { * @param capacity the capacity of this queue * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyShrinkable ArrayBlockingQueue(int capacity) { this(capacity, false); } @@ -291,7 +291,7 @@ void removeAt(final int removeIndex) { * if {@code false} the access order is unspecified. * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity, boolean fair) { + public @Modifiable @IteratorPolyShrinkable ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; @@ -316,7 +316,7 @@ void removeAt(final int removeIndex) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity, boolean fair, + public @Modifiable @IteratorPolyShrinkable ArrayBlockingQueue(int capacity, boolean fair, Collection c) { this(capacity, fair); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 5e565d20aa2e..42b7f2c02b0b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1286,7 +1286,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrinkable ConcurrentHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrinkable ConcurrentHashMap this) { KeySetView ks; if ((ks = keySet) != null) return ks; return keySet = new KeySetView(this, null); @@ -1311,7 +1311,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; return values = new ValuesView(this); @@ -1335,7 +1335,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentHashMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); @@ -2297,7 +2297,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @throws NullPointerException if the mappedValue is null */ @SideEffectFree - public @IteratorPolyMod KeySetView keySet(V mappedValue) { + public @IteratorPolyShrinkable KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); return new KeySetView(this, mappedValue); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index c69000e14e8c..6ee1f47d871b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -793,7 +793,7 @@ private E screenNullResult(@NonNull E v) { /** * Constructs an empty deque. */ - public @Modifiable @IteratorPolyMod ConcurrentLinkedDeque() { + public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedDeque() { head = tail = new Node(); } @@ -806,7 +806,7 @@ private E screenNullResult(@NonNull E v) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ConcurrentLinkedDeque(Collection c) { + public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedDeque(Collection c) { // Copy c into a private chain of Nodes Node h = null, t = null; for (E e : c) { diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 9079977b71da..514a55f20d7c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -265,7 +265,7 @@ boolean casItem(E cmp, E val) { /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public @Modifiable @IteratorPolyMod ConcurrentLinkedQueue() { + public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedQueue() { head = tail = new Node(); } @@ -278,7 +278,7 @@ boolean casItem(E cmp, E val) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ConcurrentLinkedQueue(Collection c) { + public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index 88089e87c66f..fca57cd36cb6 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -35,7 +35,7 @@ package java.util.concurrent; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -147,7 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentNavigableMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -168,7 +168,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentNavigableMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentNavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -187,5 +187,5 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentNavigableMap this); + @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 424905b57961..62b7c4986535 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1654,14 +1654,14 @@ else if (doRemove(key, v) != null) * @return a navigable set view of the keys in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); @@ -1687,7 +1687,7 @@ else if (doRemove(key, v) != null) * weakly consistent. */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; return values = new Values<>(this); @@ -1721,7 +1721,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1736,7 +1736,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3066,35 +3066,35 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SubMap this) { Values vs; if ((vs = valuesView) != null) return vs; return valuesView = new Values<>(this); } @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable SubMap this) { + public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable SubMap this) { EntrySet es; if ((es = entrySetView) != null) return es; return entrySetView = new EntrySet(this); } @SideEffectFree - public @IteratorPolyMod NavigableSet descendingKeySet() { + public @IteratorPolyShrinkable NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 31fda8731889..d1435b728f1c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -132,7 +132,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet() { + public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -144,7 +144,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -159,7 +159,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(Collection c) { + public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -172,7 +172,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(SortedSet s) { + public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -180,7 +180,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable @IteratorPolyMod ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -191,7 +191,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet clone() { + public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 83abe7bfab5b..64359e6171a2 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -154,7 +154,7 @@ public class DelayQueue extends AbstractQueue /** * Creates a new {@code DelayQueue} that is initially empty. */ - public @Modifiable @IteratorPolyMod DelayQueue() {} + public @Modifiable @IteratorPolyShrinkable DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -164,7 +164,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod DelayQueue(Collection c) { + public @Modifiable @IteratorPolyShrinkable DelayQueue(Collection c) { this.addAll(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 1e040688930a..14cfadf8ca79 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -194,7 +194,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPolyMod LinkedBlockingDeque() { + public @Modifiable @IteratorPolyShrinkable LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -204,7 +204,7 @@ static final class Node { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public @Modifiable @IteratorPolyMod LinkedBlockingDeque(int capacity) { + public @Modifiable @IteratorPolyShrinkable LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -219,7 +219,7 @@ static final class Node { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod LinkedBlockingDeque(Collection c) { + public @Modifiable @IteratorPolyShrinkable LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } 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 b61bc66101a0..3c00956bfb7d 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -264,7 +264,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPolyMod LinkedBlockingQueue() { + public @Modifiable @IteratorPolyShrinkable LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -275,7 +275,7 @@ void fullyUnlock() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public @Modifiable @IteratorPolyMod LinkedBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyShrinkable LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -291,7 +291,7 @@ void fullyUnlock() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod LinkedBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyShrinkable LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 49a1bbbc0ffe..53994bc0f49e 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1183,7 +1183,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public @Modifiable @IteratorPolyMod LinkedTransferQueue() { + public @Modifiable @IteratorPolyShrinkable LinkedTransferQueue() { head = tail = new Node(); } @@ -1196,7 +1196,7 @@ else if (s == n) // stale * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod LinkedTransferQueue(Collection c) { + public @Modifiable @IteratorPolyShrinkable LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(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 ebfd837c2ef8..9deb7bdeccde 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -210,7 +210,7 @@ public class PriorityBlockingQueue extends AbstractQueue * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyMod PriorityBlockingQueue() { + public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -223,7 +223,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyMod PriorityBlockingQueue(int initialCapacity) { + public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -239,7 +239,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyMod PriorityBlockingQueue(int initialCapacity, + public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -263,7 +263,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod PriorityBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java index 4167df7d64b9..4ad15fd4f8be 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Growable.java @@ -9,7 +9,7 @@ /** * Calling grow operations such as {@code add}, {@code addAll}, etc. on this collection will not - * result in throwing {@link UnsupportedOperationException}. + * throw {@link UnsupportedOperationException}. * *

No guarantees are made about shrink or replace operations. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java similarity index 71% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java index 8ad422162e21..fb4fd4ea8528 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java @@ -8,10 +8,10 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} method preserves + * If a collection's type is {@code @IteratorPolyShrinkable}, then its {@code iterator()} method preserves * the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has type * {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any - * collection whose type is {@code @MaybeIteratorPolyMod}, its iterator is always + * collection whose type is {@code @MaybeIteratorPolyShrinkable}, its iterator is always * {@code @Unshrinkable}. * * @checker_framework.manual #modifiability-checker Modifiability Checker @@ -19,5 +19,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeIteratorPolyMod.class) -public @interface IteratorPolyMod {} +@SubtypeOf(MaybeIteratorPolyShrinkable.class) +public @interface IteratorPolyShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java index 628c95dc13c7..c4914c496803 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeGrowable.java @@ -9,8 +9,9 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the Grow hierarchy. Represents unknown grow capability. The checker cannot - * determine whether the collection supports grow operations such as {@code add}. + * The top qualifier in the Grow hierarchy. The collection may or may not support grow operations + * such as {@code add}. The checker conservatively issues an error wherever a grow operation is + * called on a {@code @MaybeGrowable} expression. * *

This is the default qualifier for unannotated types in the Grow hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyShrinkable.java similarity index 83% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyShrinkable.java index 30f794ba7973..e48346a6d48d 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyShrinkable.java @@ -9,11 +9,11 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * For the annotated collection, The return type of {@code iterator()} is {@code @Unshrinkable}. + * For the annotated collection, the return type of {@code iterator()} is {@code @Unshrinkable}. * *

This is the default qualifier for unannotated types. * - * @see IteratorPolyMod + * @see IteratorPolyShrinkable * @checker_framework.manual #modifiability-checker Modifiability Checker */ @Documented @@ -21,4 +21,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface MaybeIteratorPolyMod {} +public @interface MaybeIteratorPolyShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java index 641d51b83b56..1b1aa7978b95 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeReplaceable.java @@ -9,9 +9,9 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the Replace hierarchy. Represents unknown replace capability. The checker - * cannot determine whether the collection supports replace operations such as {@code set} or {@code - * replaceAll}. + * The top qualifier in the Replace hierarchy. The collection may or may not support replace + * operations such as {@code set} and {@code replaceAll}. The checker conservatively issues an error + * wherever a replace operation is called on a {@code @MaybeReplaceable} expression. * *

This is the default qualifier for unannotated types in the Replace hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java index b6889579408b..2175b8951d5f 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeShrinkable.java @@ -9,9 +9,10 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the Shrink hierarchy. Represents unknown shrink capability. The checker - * cannot determine whether the collection supports shrink operations such as {@code remove} or - * {@code clear}. + * The top qualifier in the Shrink hierarchy. The collection may or may not support shrink + * operations such as {@code remove}, {@code, removeAll}, and {@code clear}. The checker + * conservatively issues an error wherever a shrink operation is called on a + * {@code @MaybeShrinkable} expression. * *

This is the default qualifier for unannotated types in the Shrink hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java index f02de1c0592c..6ea06c0065be 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -8,8 +8,8 @@ /** * Convenience alias usually meaning {@code @Growable @Shrinkable @Replaceable}. Calling a mutating - * operation (growing, shrinking, or replacing) on this collection will not result in throwing - * {@link UnsupportedOperationException}. + * operation (growing, shrinking, or replacing) on this collection will not throw {@link + * UnsupportedOperationException}. * *

As an exception, {@code @Modifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Modifiable Iterator} means diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 517762db7857..5176b1123f9d 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -7,8 +7,8 @@ * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkable}. A polymorphic * qualifier for all three modifiability hierarchies. * - *

You should write {@code @PolyModifiable} on methods that preserve or transfer modifiability, - * such as {@code List.subList()}, {@code iterator()}, and {@code stream()}. + *

Write {@code @PolyModifiable} on methods that preserve or transfer modifiability, such as + * {@code List.subList()} and {@code stream()}. * *

For example: * @@ -18,9 +18,9 @@ * } * * - * If the receiver type at a given call site is {@code @Unmodifiable}, the return type at that call - * site {@code @Unmodifiable}. If the receiver type is {@code @Modifiable}, the return type is - * {@code @Modifiable}. Likewise for growing and shrinking type qualifiers. + * At each call site, the return type is equal to the receiver type. If the receiver type is + * {@code @Growable}, the return type is {@code @Growable}. If the receiver type is + * {@code @Ungrowable}, the return type is {@code @Ungrowable}. * * @checker_framework.manual #modifiability-checker Modifiability Checker * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java index 9759df8a08b4..58a79dbd5b7a 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Replaceable.java @@ -9,7 +9,7 @@ /** * Calling replace operations such as {@code set}, {@code replaceAll}, etc. on this collection will - * not result in throwing {@link UnsupportedOperationException}. + * not throw {@link UnsupportedOperationException}. * *

No guarantees are made about grow or shrink operations. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java index 10af526c558c..39bb42266427 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Shrinkable.java @@ -8,8 +8,8 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * Calling shrink operations such as {@code remove}, {@code clear}, etc. on this collection will not - * result in throwing {@link UnsupportedOperationException}. + * Calling shrink operations such as {@code remove}, {@code removeAll}, {@code clear}, etc. on this + * collection will not throw {@link UnsupportedOperationException}. * *

No guarantees are made about grow or replace operations. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java index 3f3662d5a767..4c3390762cdc 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/UnmodifiableParam.java @@ -7,13 +7,13 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. This is a - * syntactic sugar for {@link MaybeModifiable}. It is intended to be used on parameters of methods - * that are not designed to change the parameter. This annotation is only allowed to be written - * within method or constructor parameter types, or explicit receiver parameter types. + * Convenience alias that is syntactic sugar for {@code @}{@link MaybeModifiable}. It may only be + * written within a formal parameter type. * - *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated type. + *

You can write {@code @UnmodifiableParam} to indicate that a method does not change its + * parameter. From the method's point of view, the parameter is unmodifiable. This is reference + * unmodifiability, because another alias can change the value, unlike {@code @}{@link Unmodifiable} + * which means object immutability: no alias can change the value. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java index c52ce9679d8a..eb32a3949516 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unshrinkable.java @@ -8,8 +8,8 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * Calling shrink operations such as {@code remove}, {@code clear}, etc. on this collection will - * throw {@link UnsupportedOperationException}. + * Calling shrink operations such as {@code remove}, {@code removeAll}, {@code clear}, etc. on this + * collection will throw {@link UnsupportedOperationException}. * *

No guarantees are made about grow or replace operations. * diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectFree.java b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectFree.java index da33d80443e7..db55f24f792b 100644 --- a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectFree.java +++ b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectFree.java @@ -12,8 +12,8 @@ * *

Only the visible side effects are important. The method is allowed to cache the answer to a * computationally expensive query, for instance. It is also allowed to modify newly-created - * objects, and a constructor is side-effect-free if it does not modify any objects that existed - * before it was called. + * objects. A constructor is side-effect-free if it does not modify any objects that existed before + * it was called in ways that are externally visible. * *

This annotation is important to pluggable type-checking because if some fact about an object * is known before a call to such a method, then the fact is still known afterwards, even if the From 31b62bd5c5f9f5f23400e8d5b62034ce65cb9a8c Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Fri, 29 May 2026 12:17:32 -0700 Subject: [PATCH 099/119] Push @IteratorPolyMod upward --- .../classes/java/util/AbstractCollection.java | 2 +- .../share/classes/java/util/AbstractList.java | 10 +++++----- .../share/classes/java/util/Collection.java | 10 +++++----- .../share/classes/java/util/List.java | 18 +++++++++--------- src/java.base/share/classes/java/util/Set.java | 3 ++- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 0c7375469f9f..8e87fdef2d3b 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -287,7 +287,7 @@ private static T[] finishToArray(T[] r, Iterator it) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { + public boolean add(@IteratorPolyMod @Growable @GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index bb92da589247..aab4e8b60b13 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -142,7 +142,7 @@ protected AbstractList() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { + public boolean add(@IteratorPolyMod @Growable @GuardSatisfied AbstractList this, E e) { add(size(), e); return true; } @@ -171,7 +171,7 @@ public boolean add(@Growable @GuardSatisfied AbstractList this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { + public E set(@IteratorPolyMod @Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -191,7 +191,7 @@ public E set(@Replaceable @GuardSatisfied AbstractList this, @IndexFor({"this @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { + public void add(@IteratorPolyMod @Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -207,7 +207,7 @@ public void add(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"t */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { + public E remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); } @@ -315,7 +315,7 @@ public void clear(@Shrinkable @GuardSatisfied @CanShrink AbstractList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { + public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 0e80771451f7..7e7d6eb1eb4c 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -499,7 +499,7 @@ default T[] toArray(@MaybeModifiable Collection this, IntFunction ge @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean add(@Growable @GuardSatisfied Collection this, E e); + boolean add(@IteratorPolyMod @Growable @GuardSatisfied Collection this, E e); /** * Removes a single instance of the specified element from this * collection, if it is present (optional operation). More formally, @@ -522,7 +522,7 @@ default T[] toArray(@MaybeModifiable Collection this, IntFunction ge */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean remove(@Shrinkable @GuardSatisfied @CanShrink Collection this, @UnknownSignedness Object o); + boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Collection this, @UnknownSignedness Object o); // Bulk Operations @@ -601,7 +601,7 @@ default T[] toArray(@MaybeModifiable Collection this, IntFunction ge */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink Collection this, Collection c); + boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Collection this, Collection c); /** * Removes all of the elements of this collection that satisfy the given * predicate. Errors or runtime exceptions thrown during iteration or by @@ -663,7 +663,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink Collection this, Collection c); + boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Collection this, Collection c); /** * Removes all of the elements from this collection (optional operation). * The collection will be empty after this method returns. @@ -673,7 +673,7 @@ default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection t */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void clear(@Shrinkable @GuardSatisfied @CanShrink Collection this); + void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink Collection this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index e0faf2f7f340..372221ac529b 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -310,7 +310,7 @@ public interface List extends SequencedCollection { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean add(@Growable @GuardSatisfied List this, E e); + boolean add(@IteratorPolyMod @Growable @GuardSatisfied List this, E e); /** * Removes the first occurrence of the specified element from this list, @@ -335,7 +335,7 @@ public interface List extends SequencedCollection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean remove(@Shrinkable @GuardSatisfied @CanShrink List this, @UnknownSignedness Object o); + boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink List this, @UnknownSignedness Object o); // Bulk Modification Operations @@ -416,7 +416,7 @@ public interface List extends SequencedCollection { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmptyIf(result = true, expression = "this") - boolean addAll(@Growable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); + boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); /** * Removes from this list all of its elements that are contained in the @@ -438,7 +438,7 @@ public interface List extends SequencedCollection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean removeAll(@Shrinkable @GuardSatisfied @CanShrink List this, Collection c); + boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink List this, Collection c); /** * Retains only the elements in this list that are contained in the @@ -462,7 +462,7 @@ public interface List extends SequencedCollection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean retainAll(@Shrinkable @GuardSatisfied @CanShrink List this, Collection c); + boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink List this, Collection c); /** * Replaces each element of this list with the result of applying the @@ -583,7 +583,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this); + void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink List this); // Comparison and hashing @@ -660,7 +660,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this, @IndexFor({"this"}) int index, E element); + E set(@IteratorPolyMod @Replaceable @GuardSatisfied List this, @IndexFor({"this"}) int index, E element); /** * Inserts the specified element at the specified position in this list @@ -685,7 +685,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this, @IndexOrHigh({"this"}) int index, E element); + void add(@IteratorPolyMod @Growable @GuardSatisfied List this, @IndexOrHigh({"this"}) int index, E element); /** * Removes the element at the specified position in this list (optional * operation). Shifts any subsequent elements to the left (subtracts one @@ -702,7 +702,7 @@ default void sort(@IteratorPolyMod @Replaceable List this, Comparator this, @IndexFor({"this"}) int index); + E remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink List this, @IndexFor({"this"}) int index); // Search Operations diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 2e6095c586f7..b13a4a7ed234 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -415,7 +416,7 @@ public interface Set extends Collection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean removeAll(@Shrinkable @GuardSatisfied Set this, Collection c); + boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied Set this, Collection c); /** * Removes all of the elements from this set (optional operation). From 25213e03e0f602458677eada40e43b5128f6fda8 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Fri, 29 May 2026 14:33:05 -0700 Subject: [PATCH 100/119] rename iteratorPolyShrinkable back to IteratorPolyMod --- .../classes/java/util/AbstractCollection.java | 10 ++-- .../share/classes/java/util/AbstractList.java | 4 +- .../share/classes/java/util/AbstractMap.java | 8 +-- .../java/util/AbstractSequentialList.java | 10 ++-- .../share/classes/java/util/AbstractSet.java | 4 +- .../share/classes/java/util/ArrayDeque.java | 10 ++-- .../share/classes/java/util/ArrayList.java | 10 ++-- .../share/classes/java/util/Collection.java | 4 +- .../share/classes/java/util/Collections.java | 52 +++++++++---------- .../share/classes/java/util/EnumMap.java | 8 +-- .../share/classes/java/util/EnumSet.java | 30 +++++------ .../share/classes/java/util/HashMap.java | 8 +-- .../share/classes/java/util/HashSet.java | 14 ++--- .../share/classes/java/util/Hashtable.java | 8 +-- .../classes/java/util/IdentityHashMap.java | 8 +-- .../classes/java/util/LinkedHashMap.java | 14 ++--- .../classes/java/util/LinkedHashSet.java | 10 ++-- .../share/classes/java/util/LinkedList.java | 8 +-- .../share/classes/java/util/List.java | 6 +-- .../share/classes/java/util/Map.java | 8 +-- .../share/classes/java/util/NavigableMap.java | 6 +-- .../classes/java/util/PriorityQueue.java | 16 +++--- .../share/classes/java/util/Properties.java | 8 +-- .../java/util/ReverseOrderSortedMapView.java | 10 ++-- .../java/util/SequencedCollection.java | 6 +-- .../share/classes/java/util/SortedMap.java | 8 +-- .../share/classes/java/util/Stack.java | 4 +- .../share/classes/java/util/TreeMap.java | 22 ++++---- .../share/classes/java/util/TreeSet.java | 14 ++--- .../share/classes/java/util/Vector.java | 12 ++--- .../share/classes/java/util/WeakHashMap.java | 8 +-- .../util/concurrent/ArrayBlockingQueue.java | 8 +-- .../util/concurrent/ConcurrentHashMap.java | 10 ++-- .../concurrent/ConcurrentLinkedDeque.java | 6 +-- .../concurrent/ConcurrentLinkedQueue.java | 6 +-- .../concurrent/ConcurrentNavigableMap.java | 8 +-- .../concurrent/ConcurrentSkipListMap.java | 22 ++++---- .../concurrent/ConcurrentSkipListSet.java | 14 ++--- .../java/util/concurrent/DelayQueue.java | 6 +-- .../util/concurrent/LinkedBlockingDeque.java | 8 +-- .../util/concurrent/LinkedBlockingQueue.java | 8 +-- .../util/concurrent/LinkedTransferQueue.java | 6 +-- .../concurrent/PriorityBlockingQueue.java | 10 ++-- 43 files changed, 230 insertions(+), 230 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index f90a0ef7df37..0c7375469f9f 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -310,7 +310,7 @@ public boolean add(@Growable @GuardSatisfied AbstractCollection this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean remove(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { + public boolean remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) { @@ -407,7 +407,7 @@ public boolean addAll(@Growable @GuardSatisfied AbstractCollection this, Coll */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -444,7 +444,7 @@ public boolean removeAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @Ca */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean retainAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { + public boolean retainAll(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; Iterator it = iterator(); @@ -475,7 +475,7 @@ public boolean retainAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @Ca */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void clear(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { + public void clear(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { it.next(); diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index fb178cdb4dd8..bb92da589247 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -663,7 +663,7 @@ public int hashCode(@MaybeModifiable @GuardSatisfied AbstractList this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - protected void removeRange(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { + protected void removeRange(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i this) { * method will not all return the same set. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied AbstractMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { @@ -469,7 +469,7 @@ public boolean contains(@UnknownSignedness Object k) { * method will not all return the same collection. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied AbstractMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { @@ -527,7 +527,7 @@ public boolean contains(@UnknownSignedness Object v) { } @SideEffectFree - public abstract @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); + public abstract @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@PolyModifiable Entry<@KeyFor({"this"}) K,V>> entrySet(@PolyModifiable @GuardSatisfied AbstractMap this); // Comparison and hashing diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 9eb9c7645f84..750d0de9b2ce 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -136,7 +136,7 @@ public E get(@MaybeModifiable @GuardSatisfied AbstractSequentialList this, in @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E set(@IteratorPolyShrinkable @Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public E set(@IteratorPolyMod @Replaceable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { ListIterator e = listIterator(index); E oldVal = e.next(); @@ -170,7 +170,7 @@ public E set(@IteratorPolyShrinkable @Replaceable @GuardSatisfied AbstractSequen @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void add(@IteratorPolyShrinkable @Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { + public void add(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialList this, int index, E element) { try { listIterator(index).add(element); } catch (NoSuchElementException exc) { @@ -197,7 +197,7 @@ public void add(@IteratorPolyShrinkable @Growable @GuardSatisfied AbstractSequen */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public E remove(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { + public E remove(@IteratorPolyMod @Shrinkable @GuardSatisfied @CanShrink AbstractSequentialList this, int index) { try { ListIterator e = listIterator(index); E outCast = e.next(); @@ -242,7 +242,7 @@ public E remove(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied @CanShrink A */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean addAll(@IteratorPolyShrinkable @Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { + public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractSequentialList this, int index, Collection c) { try { boolean modified = false; ListIterator e1 = listIterator(index); diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index c28ed04cc7b3..fa3f8e9e2d48 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -180,7 +180,7 @@ public int hashCode(@MaybeModifiable @GuardSatisfied AbstractSet this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean removeAll(@IteratorPolyShrinkable @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { + public boolean removeAll(@IteratorPolyMod @Shrinkable @GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 444c9c041a1f..df6f3a597294 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -203,7 +203,7 @@ private int newCapacity(int needed, int jump) { * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */ - public @Modifiable @IteratorPolyShrinkable ArrayDeque() { + public @Modifiable @IteratorPolyMod ArrayDeque() { elements = new Object[16 + 1]; } @@ -213,7 +213,7 @@ private int newCapacity(int needed, int jump) { * * @param numElements lower bound on initial capacity of the deque */ - public @Modifiable @IteratorPolyShrinkable ArrayDeque(@NonNegative int numElements) { + public @Modifiable @IteratorPolyMod ArrayDeque(@NonNegative int numElements) { elements = new Object[(numElements < 1) ? 1 : (numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : @@ -230,7 +230,7 @@ private int newCapacity(int needed, int jump) { * @param c the collection whose elements are to be placed into the deque * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty ArrayDeque(@PolyNonEmpty Collection c) { this(c.size()); copyElements(c); } @@ -1245,7 +1245,7 @@ private T[] toArray(Class klazz) { * @return a copy of this deque */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable ArrayDeque clone(@GuardSatisfied ArrayDeque this) { + public @Modifiable @IteratorPolyMod ArrayDeque clone(@GuardSatisfied ArrayDeque this) { try { @SuppressWarnings("unchecked") ArrayDeque result = (ArrayDeque) super.clone(); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 415fa480cc2d..dd0a291b1960 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -183,7 +183,7 @@ public class ArrayList extends AbstractList * is negative */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable ArrayList(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyMod ArrayList(@NonNegative int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { @@ -198,7 +198,7 @@ public class ArrayList extends AbstractList * Constructs an empty list with an initial capacity of ten. */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable ArrayList() { + public @Modifiable @IteratorPolyMod ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } @@ -211,7 +211,7 @@ public class ArrayList extends AbstractList * @throws NullPointerException if the specified collection is null */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty ArrayList(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { @@ -385,7 +385,7 @@ int lastIndexOfRange(@GuardSatisfied @Nullable @UnknownSignedness Object o, int * @return a clone of this {@code ArrayList} instance */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied ArrayList this) { + public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied ArrayList this) { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 29850ff68fb0..0e80771451f7 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -626,7 +626,7 @@ default T[] toArray(@MaybeModifiable Collection this, IntFunction ge */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default boolean removeIf(@IteratorPolyShrinkable @Shrinkable @CanShrink Collection this, Predicate filter) { + default boolean removeIf(@IteratorPolyMod @Shrinkable @CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 93befcbef31d..1426e5d2cd0b 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -178,7 +178,7 @@ private Collections() { */ @SuppressWarnings("unchecked") // @SideEffectsOnly("#1") - public static > void sort(@IteratorPolyShrinkable @Replaceable List list) { + public static > void sort(@IteratorPolyMod @Replaceable List list) { list.sort(null); } @@ -213,7 +213,7 @@ public static > void sort(@IteratorPolyShrinkabl */ @SuppressWarnings({"unchecked", "rawtypes"}) // @SideEffectsOnly("#1") - public static void sort(@IteratorPolyShrinkable @Replaceable List list, @Nullable Comparator c) { + public static void sort(@IteratorPolyMod @Replaceable List list, @Nullable Comparator c) { list.sort(c); } @@ -420,7 +420,7 @@ else if (cmp > 0) * @see List#reversed List.reversed */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void reverse(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list) { + public static void reverse(@IteratorPolyMod @Replaceable @GuardSatisfied List list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i list) { + public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); // harmless race. @@ -490,7 +490,7 @@ public static void shuffle(@IteratorPolyShrinkable @Replaceable @GuardSatisfied * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void shuffle(@IteratorPolyShrinkable @Replaceable List list, Random rnd) { + public static void shuffle(@IteratorPolyMod @Replaceable List list, Random rnd) { shuffle(list, (RandomGenerator) rnd); } @@ -519,7 +519,7 @@ public static void shuffle(@IteratorPolyShrinkable @Replaceable List list, Ra * @since 21 */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static void shuffle(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list, RandomGenerator rnd) { + public static void shuffle(@IteratorPolyMod @Replaceable @GuardSatisfied List list, RandomGenerator rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) @@ -586,7 +586,7 @@ private static void swap(Object[] arr, int i, int j) { * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the {@code set} operation. */ - public static void fill(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list, T obj) { + public static void fill(@IteratorPolyMod @Replaceable @GuardSatisfied List list, T obj) { int size = list.size(); if (size < FILL_THRESHOLD || list instanceof RandomAccess) { @@ -619,7 +619,7 @@ public static void fill(@IteratorPolyShrinkable @Replaceable @GuardSatisfied * @throws UnsupportedOperationException if the destination list's * list-iterator does not support the {@code set} operation. */ - public static void copy(@IteratorPolyShrinkable @Replaceable List dest, @MaybeModifiable List src) { + public static void copy(@IteratorPolyMod @Replaceable List dest, @MaybeModifiable List src) { int srcSize = src.size(); if (srcSize > dest.size()) throw new IndexOutOfBoundsException("Source does not fit in dest"); @@ -847,7 +847,7 @@ public static T max(@MaybeModifiable Collection coll, @Nullable * its list-iterator does not support the {@code set} operation. * @since 1.4 */ - public static void rotate(@IteratorPolyShrinkable @Replaceable @GuardSatisfied List list, int distance) { + public static void rotate(@IteratorPolyMod @Replaceable @GuardSatisfied List list, int distance) { if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) rotate1(list, distance); else @@ -913,7 +913,7 @@ private static void rotate2(List list, int distance) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public static boolean replaceAll(@IteratorPolyShrinkable @Replaceable List list, @Nullable T oldVal, T newVal) { + public static boolean replaceAll(@IteratorPolyMod @Replaceable List list, @Nullable T oldVal, T newVal) { boolean result = false; int size = list.size(); if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { @@ -1094,7 +1094,7 @@ public static boolean replaceAll(@IteratorPolyShrinkable @Replaceable List @IteratorPolyShrinkable @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { + public static @IteratorPolyMod @Unmodifiable @PolyGrowShrink @PolyNonEmpty Collection unmodifiableCollection(@MaybeModifiable @PolyGrowShrink @PolyNonEmpty Collection c) { if (c.getClass() == UnmodifiableCollection.class) { return (Collection) c; } @@ -1340,7 +1340,7 @@ public E removeLast() { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @IteratorPolyShrinkable @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@MaybeModifiable @PolyNonEmpty Set s) { + public static @IteratorPolyMod @Unmodifiable @PolyNonEmpty Set unmodifiableSet(@MaybeModifiable @PolyNonEmpty Set s) { // Not checking for subclasses because of heap pollution and information leakage. if (s.getClass() == UnmodifiableSet.class) { return (Set) s; @@ -3226,7 +3226,7 @@ public void clear() { private transient Set> entrySet; private transient Collection values; - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable SynchronizedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable SynchronizedMap this) { synchronized (mutex) { if (keySet==null) keySet = new SynchronizedSet<>(m.keySet(), mutex); @@ -3235,7 +3235,7 @@ public void clear() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable SynchronizedMap this) { synchronized (mutex) { if (entrySet==null) entrySet = new SynchronizedSet<>(m.entrySet(), mutex); @@ -3243,7 +3243,7 @@ public void clear() { } } - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SynchronizedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SynchronizedMap this) { synchronized (mutex) { if (values==null) values = new SynchronizedCollection<>(m.values(), mutex); @@ -3552,19 +3552,19 @@ public NavigableMap descendingMap() { } } - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SynchronizedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SynchronizedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SynchronizedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable SynchronizedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable SynchronizedNavigableMap this) { synchronized (mutex) { return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } @@ -4394,8 +4394,8 @@ private String badValueMsg(Object value) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable CheckedMap this) { return m.keySet(); } - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable CheckedMap this) { return m.values(); } + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable CheckedMap this) { return m.keySet(); } + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable CheckedMap this) { return m.values(); } @Pure public boolean equals(Object o) { return o == this || m.equals(o); } @Pure @@ -4436,7 +4436,7 @@ public void putAll(Map t) { private transient Set> entrySet; @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable CheckedMap this) { if (entrySet==null) entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); return entrySet; @@ -4966,17 +4966,17 @@ public NavigableMap descendingMap() { return checkedNavigableMap(nm.descendingMap(), keyType, valueType); } - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable CheckedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable CheckedNavigableMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable CheckedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable CheckedNavigableMap this) { return checkedNavigableSet(nm.navigableKeySet(), keyType); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable CheckedNavigableMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable CheckedNavigableMap this) { return checkedNavigableSet(nm.descendingKeySet(), keyType); } @@ -6358,7 +6358,7 @@ public T nextElement(/*@NonEmpty Enumeration this*/) { * @see Enumeration * @see ArrayList */ - public static @Modifiable @IteratorPolyShrinkable ArrayList list(Enumeration e) { + public static @Modifiable @IteratorPolyMod ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 41fe09f88534..93bcc3f6da52 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -426,7 +426,7 @@ public void clear(@Shrinkable EnumMap this) { * @return a set view of the keys contained in this enum map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable EnumMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable EnumMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -474,7 +474,7 @@ public void clear(@Shrinkable KeySet this) { * @return a collection view of the values contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable EnumMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable EnumMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -528,7 +528,7 @@ public void clear(@Shrinkable Values this) { * @return a set view of the mappings contained in this enum map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable EnumMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index 86107f467b4b..5dedb0466f8e 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; @@ -105,7 +105,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ final transient Enum[] universe; - @Modifiable @IteratorPolyShrinkable EnumSet(ClasselementType, Enum[] universe) { + @Modifiable @IteratorPolyMod EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; this.universe = universe; } @@ -119,7 +119,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An empty enum set of the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPolyShrinkable EnumSet noneOf(Class elementType) { + public static > @Modifiable @IteratorPolyMod EnumSet noneOf(Class elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); @@ -140,7 +140,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return An enum set containing all the elements in the specified type. * @throws NullPointerException if {@code elementType} is null */ - public static > @Modifiable @IteratorPolyShrinkable EnumSet allOf(Class elementType) { + public static > @Modifiable @IteratorPolyMod EnumSet allOf(Class elementType) { EnumSet result = noneOf(elementType); result.addAll(); return result; @@ -163,7 +163,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code s} is null */ @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet copyOf(EnumSet s) { + public static > @Modifiable @IteratorPolyMod EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -182,7 +182,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if {@code c} is null */ @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet copyOf(Collection c) { + public static > @Modifiable @IteratorPolyMod EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); } else { @@ -207,7 +207,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return The complement of the specified set in this set * @throws NullPointerException if {@code s} is null */ - public static > @Modifiable @IteratorPolyShrinkable EnumSet complementOf(EnumSet s) { + public static > @Modifiable @IteratorPolyMod EnumSet complementOf(EnumSet s) { EnumSet result = copyOf(s); result.complement(); return result; @@ -228,7 +228,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified element */ @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e) { + public static > @Modifiable @IteratorPolyMod EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); return result; @@ -250,7 +250,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2) { + public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -274,7 +274,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2, E e3) { + public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -300,7 +300,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing the specified elements */ @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2, E e3, E e4) { + public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); result.add(e2); @@ -327,7 +327,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ - public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E e1, E e2, E e3, E e4, + public static > @Modifiable @IteratorPolyMod EnumSet of(E e1, E e2, E e3, E e4, E e5) { EnumSet result = noneOf(e1.getDeclaringClass()); @@ -355,7 +355,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SafeVarargs @SideEffectFree - public static > @Modifiable @IteratorPolyShrinkable EnumSet of(E first, E... rest) { + public static > @Modifiable @IteratorPolyMod EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) @@ -377,7 +377,7 @@ public abstract sealed class EnumSet> extends AbstractSet * @return an enum set initially containing all of the elements in the * range defined by the two specified endpoints */ - public static > @Modifiable @IteratorPolyShrinkable EnumSet range(E from, E to) { + public static > @Modifiable @IteratorPolyMod EnumSet range(E from, E to) { if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to); EnumSet result = noneOf(from.getDeclaringClass()); @@ -399,7 +399,7 @@ public abstract sealed class EnumSet> extends AbstractSet */ @SuppressWarnings("unchecked") @SideEffectFree - public @Modifiable @IteratorPolyShrinkable EnumSet clone() { + public @Modifiable @IteratorPolyMod EnumSet clone() { try { return (EnumSet) super.clone(); } catch(CloneNotSupportedException e) { diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 37dd28cd9805..e2e56d733575 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -963,7 +963,7 @@ public boolean containsValue(@GuardSatisfied HashMap this, @GuardSatisfied * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied HashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1103,7 +1103,7 @@ public final void forEach(Consumer action) { * @return a view of the values contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied HashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1170,7 +1170,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 7e2cbc161601..5d00823e2713 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -126,7 +126,7 @@ public class HashSet * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPolyShrinkable HashSet() { + public @Modifiable @IteratorPolyMod HashSet() { map = new HashMap<>(); } @@ -139,7 +139,7 @@ public class HashSet * @param c the collection whose elements are to be placed into this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty HashSet(@PolyNonEmpty Collection c) { map = HashMap.newHashMap(Math.max(c.size(), 12)); addAll(c); } @@ -157,7 +157,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPolyShrinkable HashSet(@NonNegative int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPolyMod HashSet(@NonNegative int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } @@ -173,7 +173,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPolyShrinkable HashSet(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyMod HashSet(@NonNegative int initialCapacity) { map = new HashMap<>(initialCapacity); } @@ -190,7 +190,7 @@ public class HashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - @Modifiable @IteratorPolyShrinkable HashSet(int initialCapacity, float loadFactor, boolean dummy) { + @Modifiable @IteratorPolyMod HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } @@ -297,7 +297,7 @@ public void clear(@Shrinkable @GuardSatisfied HashSet this) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied HashSet this) { + public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied HashSet this) { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 25d6cb5d38e6..cb7eaf080620 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -710,7 +710,7 @@ private Iterator getIterator(int type) { * @since 1.2 */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied Hashtable this) { if (keySet == null) keySet = Collections.synchronizedSet(new KeySet(), this); return keySet; @@ -759,7 +759,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied Hashtable this) { if (entrySet==null) entrySet = Collections.synchronizedSet(new EntrySet(), this); return entrySet; @@ -850,7 +850,7 @@ public void clear() { * @since 1.2 */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied Hashtable this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied Hashtable this) { if (values==null) values = Collections.synchronizedCollection(new ValueCollection(), this); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 14de6a36e83a..13ad5906714e 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1049,7 +1049,7 @@ private void checkIndexForEntryUse() { * @see System#identityHashCode(Object) */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -1169,7 +1169,7 @@ public Spliterator spliterator() { * {@code containsAll} methods. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied IdentityHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1287,7 +1287,7 @@ public Spliterator spliterator() { * @return a set view of the identity-mappings contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied IdentityHashMap this) { Set> es = entrySet; if (es != null) return es; diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index e0a284667e46..2dff6128f0f6 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -661,7 +661,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable LinkedHashMap this) { return sequencedKeySet(); } @@ -828,7 +828,7 @@ public SequencedSet reversed() { * @return a view of the values contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable LinkedHashMap this) { return sequencedValues(); } @@ -949,7 +949,7 @@ public SequencedCollection reversed() { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied LinkedHashMap this) { return sequencedEntrySet(); } @@ -1268,17 +1268,17 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReversedLinkedHashMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReversedLinkedHashMapView this) { return base.sequencedKeySet().reversed(); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReversedLinkedHashMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReversedLinkedHashMapView this) { return base.sequencedValues().reversed(); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReversedLinkedHashMapView this) { return base.sequencedEntrySet().reversed(); } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 0f2185dc6a6d..b0cd7488430c 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -155,7 +155,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive */ - public @Modifiable @IteratorPolyShrinkable LinkedHashSet(int initialCapacity, float loadFactor) { + public @Modifiable @IteratorPolyMod LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } @@ -171,7 +171,7 @@ public class LinkedHashSet * @throws IllegalArgumentException if the initial capacity is less * than zero */ - public @Modifiable @IteratorPolyShrinkable LinkedHashSet(int initialCapacity) { + public @Modifiable @IteratorPolyMod LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } @@ -179,7 +179,7 @@ public class LinkedHashSet * Constructs a new, empty linked hash set with the default initial * capacity (16) and load factor (0.75). */ - public @Modifiable @IteratorPolyShrinkable LinkedHashSet() { + public @Modifiable @IteratorPolyMod LinkedHashSet() { super(16, .75f, true); } @@ -193,7 +193,7 @@ public class LinkedHashSet * this set * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyShrinkable LinkedHashSet(Collection c) { + public @Modifiable @IteratorPolyMod LinkedHashSet(Collection c) { super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true); addAll(c); } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index 66412ec7c80d..f8ee1602669f 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -32,7 +32,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -144,7 +144,7 @@ void dataStructureInvariants() { /** * Constructs an empty list. */ - public @Modifiable @IteratorPolyShrinkable LinkedList() { + public @Modifiable @IteratorPolyMod LinkedList() { } /** @@ -155,7 +155,7 @@ void dataStructureInvariants() { * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty LinkedList(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -1149,7 +1149,7 @@ private LinkedList superClone() { * @return a shallow copy of this {@code LinkedList} instance */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied LinkedList this) { + public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied LinkedList this) { LinkedList clone = superClone(); // Put clone into "virgin" state diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 06e3b0378b3a..e0faf2f7f340 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -34,7 +34,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -494,7 +494,7 @@ public interface List extends SequencedCollection { * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - default void replaceAll(@IteratorPolyShrinkable @Replaceable List this, UnaryOperator operator) { + default void replaceAll(@IteratorPolyMod @Replaceable List this, UnaryOperator operator) { Objects.requireNonNull(operator); final ListIterator li = this.listIterator(); while (li.hasNext()) { @@ -564,7 +564,7 @@ default void replaceAll(@IteratorPolyShrinkable @Replaceable List this, Unary @SuppressWarnings({"unchecked", "rawtypes"}) // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void sort(@IteratorPolyShrinkable @Replaceable List this, Comparator c) { + default void sort(@IteratorPolyMod @Replaceable List this, Comparator c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator i = this.listIterator(); diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 03a19c816ba2..4ea0da0de19a 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -404,7 +404,7 @@ public interface Map { * @return a set view of the keys contained in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -422,7 +422,7 @@ public interface Map { * @return a collection view of the values contained in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable @PolyNonEmpty Collection values(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Collection values(@PolyShrinkable @GuardSatisfied @PolyNonEmpty Map this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -441,7 +441,7 @@ public interface Map { * @return a set view of the mappings contained in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); + @IteratorPolyMod @PolyShrinkable @Ungrowable @PolyNonEmpty Set> entrySet(@PolyModifiable @GuardSatisfied @PolyNonEmpty Map this); /** * A map entry (key-value pair). The Entry may be unmodifiable, or the diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 256e88b9449a..51d379b92838 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -36,7 +36,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -313,7 +313,7 @@ public interface NavigableMap extends SortedMap { * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable NavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable NavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -330,7 +330,7 @@ public interface NavigableMap extends SortedMap { * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable NavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable NavigableMap this); /** * Returns a view of the portion of this map whose keys range from diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 031a0c01a81f..b5c3777f9d18 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -153,7 +153,7 @@ public class PriorityQueue extends AbstractQueue * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyShrinkable PriorityQueue() { + public @Modifiable @IteratorPolyMod PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -166,7 +166,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyShrinkable PriorityQueue(@Positive int initialCapacity) { + public @Modifiable @IteratorPolyMod PriorityQueue(@Positive int initialCapacity) { this(initialCapacity, null); } @@ -179,7 +179,7 @@ public class PriorityQueue extends AbstractQueue * natural ordering} of the elements will be used. * @since 1.8 */ - public @Modifiable @IteratorPolyShrinkable PriorityQueue(Comparator comparator) { + public @Modifiable @IteratorPolyMod PriorityQueue(Comparator comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); } @@ -194,7 +194,7 @@ public class PriorityQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 */ - public @Modifiable @IteratorPolyShrinkable PriorityQueue(@Positive int initialCapacity, + public @Modifiable @IteratorPolyMod PriorityQueue(@Positive int initialCapacity, Comparator comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility @@ -220,7 +220,7 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty PriorityQueue(@PolyNonEmpty Collection c) { if (c instanceof SortedSet) { SortedSet ss = (SortedSet) c; this.comparator = (Comparator) ss.comparator(); @@ -251,7 +251,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified priority queue or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable PriorityQueue(PriorityQueue c) { + public @Modifiable @IteratorPolyMod PriorityQueue(PriorityQueue c) { this.comparator = (Comparator) c.comparator(); initFromPriorityQueue(c); } @@ -269,7 +269,7 @@ else if (c instanceof PriorityQueue) { * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable PriorityQueue(SortedSet c) { + public @Modifiable @IteratorPolyMod PriorityQueue(SortedSet c) { this.comparator = (Comparator) c.comparator(); initElementsFromCollection(c); } diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 7f51a735af03..0d4b048197c7 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -27,7 +27,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1412,19 +1412,19 @@ public synchronized String toString() { @Override @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrinkable Properties this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor("this") Object> keySet(@PolyShrinkable Properties this) { return Collections.synchronizedSet(map.keySet(), this); } @Override @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable Properties this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable Properties this) { return Collections.synchronizedCollection(map.values(), this); } @Override @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Properties this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Properties this) { return Collections.synchronizedSet(new EntrySet(map.entrySet()), this); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 4dbf8608c87d..c7cf58a7393f 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -115,7 +115,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReverseOrderSortedMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE @SideEffectFree @@ -130,7 +130,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReverseOrderSortedMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ReverseOrderSortedMapView this) { return new AbstractCollection<>() { // inherit add(), which throws UOE @SideEffectFree @@ -145,7 +145,7 @@ public int size() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable ReverseOrderSortedMapView this) { return new AbstractSet<>() { // inherit add(), which throws UOE @SideEffectFree @@ -438,7 +438,7 @@ public String toString() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Submap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable Submap this) { return new AbstractSet<>() { @SideEffectFree public Iterator> iterator() { diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 8b28c96b2220..2bfbc7336e52 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -193,7 +193,7 @@ default E getLast() { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeFirst(@IteratorPolyShrinkable @Shrinkable SequencedCollection this) { + default E removeFirst(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.iterator(); E e = it.next(); it.remove(); @@ -217,7 +217,7 @@ default E removeFirst(@IteratorPolyShrinkable @Shrinkable SequencedCollection */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default E removeLast(@IteratorPolyShrinkable @Shrinkable SequencedCollection this) { + default E removeLast(@IteratorPolyMod @Shrinkable SequencedCollection this) { var it = this.reversed().iterator(); E e = it.next(); it.remove(); diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index f313cc7706e1..5a7c0460749d 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -26,7 +26,7 @@ package java.util; import org.checkerframework.checker.lock.qual.GuardSatisfied; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -265,7 +265,7 @@ public interface SortedMap extends SequencedMap { * ascending order */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied SortedMap this); /** * Returns a {@link Collection} view of the values contained in this map. @@ -286,7 +286,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied SortedMap this); /** * Returns a {@link Set} view of the mappings contained in this map. @@ -307,7 +307,7 @@ public interface SortedMap extends SequencedMap { * sorted in ascending key order */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied SortedMap this); /** * Throws {@code UnsupportedOperationException}. The encounter order induced by this diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index ff0d9802863a..ab8c4b91a1da 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.CanShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -67,7 +67,7 @@ public class Stack extends Vector { /** * Creates an empty Stack. */ - public @Modifiable @IteratorPolyShrinkable Stack() { + public @Modifiable @IteratorPolyMod Stack() { } /** diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 7d445e2fcbe7..7a81625ea84a 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1199,7 +1199,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * operations. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1207,7 +1207,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> navigableKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } @@ -1216,7 +1216,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @since 1.6 */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet<@KeyFor({"this"}) K> descendingKeySet(@PolyShrinkable @GuardSatisfied TreeMap this) { return descendingMap().navigableKeySet(); } @@ -1242,7 +1242,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1274,7 +1274,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied TreeMap this) { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } @@ -2109,19 +2109,19 @@ public final Map.Entry pollLastEntry(@Shrinkable NavigableSubMap this) transient KeySet navigableKeySetView; @SideEffectFree - public final @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable NavigableSubMap this) { + public final @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable NavigableSubMap this) { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : (navigableKeySetView = new TreeMap.KeySet<>(this)); } @SideEffectFree - public final @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable NavigableSubMap this) { + public final @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable NavigableSubMap this) { return navigableKeySet(); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable NavigableSubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable NavigableSubMap this) { return descendingMap().navigableKeySet(); } @@ -2466,7 +2466,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable AscendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); } @@ -2560,7 +2560,7 @@ public Iterator> iterator() { } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable DescendingSubMap this) { EntrySetView es = entrySetView; return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index ebf216c5f226..0b5a0ab42538 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -131,7 +131,7 @@ public class TreeSet extends AbstractSet /** * Constructs a set backed by the specified navigable map. */ - @Modifiable @IteratorPolyShrinkable TreeSet(NavigableMap m) { + @Modifiable @IteratorPolyMod TreeSet(NavigableMap m) { this.m = m; } @@ -148,7 +148,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable @IteratorPolyShrinkable TreeSet() { + public @Modifiable @IteratorPolyMod TreeSet() { this(new TreeMap<>()); } @@ -165,7 +165,7 @@ public class TreeSet extends AbstractSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyShrinkable TreeSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyMod TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -183,7 +183,7 @@ public class TreeSet extends AbstractSet * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -565,7 +565,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied TreeSet this) { + public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index 01287b8fdea8..40256d67eb7a 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; @@ -167,7 +167,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPolyShrinkable Vector(@NonNegative int initialCapacity, int capacityIncrement) { + public @Modifiable @IteratorPolyMod Vector(@NonNegative int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ @@ -184,7 +184,7 @@ public class Vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ - public @Modifiable @IteratorPolyShrinkable Vector(@NonNegative int initialCapacity) { + public @Modifiable @IteratorPolyMod Vector(@NonNegative int initialCapacity) { this(initialCapacity, 0); } @@ -193,7 +193,7 @@ public class Vector * has size {@code 10} and its standard capacity increment is * zero. */ - public @Modifiable @IteratorPolyShrinkable Vector() { + public @Modifiable @IteratorPolyMod Vector() { this(10); } @@ -207,7 +207,7 @@ public class Vector * @throws NullPointerException if the specified collection is null * @since 1.2 */ - public @Modifiable @IteratorPolyShrinkable @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { + public @Modifiable @IteratorPolyMod @PolyNonEmpty Vector(@PolyNonEmpty Collection c) { Object[] a = c.toArray(); elementCount = a.length; if (c.getClass() == ArrayList.class) { @@ -721,7 +721,7 @@ public synchronized void removeAllElements(@Shrinkable @GuardSatisfied @CanShrin * @return a clone of this vector */ @SideEffectFree - public synchronized @Modifiable @IteratorPolyShrinkable Object clone(@GuardSatisfied Vector this) { + public synchronized @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied Vector this) { try { @SuppressWarnings("unchecked") Vector v = (Vector) super.clone(); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index fc77fa2b261e..64ffd9d6764f 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -935,7 +935,7 @@ public Map.Entry next(@NonEmpty EntryIterator this) { * operations. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable @GuardSatisfied WeakHashMap this) { Set ks = keySet; if (ks == null) { ks = new KeySet(); @@ -998,7 +998,7 @@ public Spliterator spliterator() { * support the {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable @GuardSatisfied WeakHashMap this) { Collection vs = values; if (vs == null) { vs = new Values(); @@ -1051,7 +1051,7 @@ public Spliterator spliterator() { * {@code add} or {@code addAll} operations. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied WeakHashMap this) { Set> es = entrySet; return es != null ? es : (entrySet = new EntrySet()); } 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 534500453a2c..fbdcfa6bd5ff 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -277,7 +277,7 @@ void removeAt(final int removeIndex) { * @param capacity the capacity of this queue * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPolyShrinkable ArrayBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity) { this(capacity, false); } @@ -291,7 +291,7 @@ void removeAt(final int removeIndex) { * if {@code false} the access order is unspecified. * @throws IllegalArgumentException if {@code capacity < 1} */ - public @Modifiable @IteratorPolyShrinkable ArrayBlockingQueue(int capacity, boolean fair) { + public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; @@ -316,7 +316,7 @@ void removeAt(final int removeIndex) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable ArrayBlockingQueue(int capacity, boolean fair, + public @Modifiable @IteratorPolyMod ArrayBlockingQueue(int capacity, boolean fair, Collection c) { this(capacity, fair); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 42b7f2c02b0b..5e565d20aa2e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1286,7 +1286,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrinkable ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable KeySetView<@KeyFor({"this"}) K,V> keySet(@PolyShrinkable ConcurrentHashMap this) { KeySetView ks; if ((ks = keySet) != null) return ks; return keySet = new KeySetView(this, null); @@ -1311,7 +1311,7 @@ else if ((fh = f.hash) == MOVED) { * @return the collection view */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentHashMap this) { ValuesView vs; if ((vs = values) != null) return vs; return values = new ValuesView(this); @@ -1335,7 +1335,7 @@ else if ((fh = f.hash) == MOVED) { * @return the set view */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentHashMap this) { EntrySetView es; if ((es = entrySet) != null) return es; return entrySet = new EntrySetView(this); @@ -2297,7 +2297,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @throws NullPointerException if the mappedValue is null */ @SideEffectFree - public @IteratorPolyShrinkable KeySetView keySet(V mappedValue) { + public @IteratorPolyMod KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); return new KeySetView(this, mappedValue); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 6ee1f47d871b..c69000e14e8c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -793,7 +793,7 @@ private E screenNullResult(@NonNull E v) { /** * Constructs an empty deque. */ - public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedDeque() { + public @Modifiable @IteratorPolyMod ConcurrentLinkedDeque() { head = tail = new Node(); } @@ -806,7 +806,7 @@ private E screenNullResult(@NonNull E v) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedDeque(Collection c) { + public @Modifiable @IteratorPolyMod ConcurrentLinkedDeque(Collection c) { // Copy c into a private chain of Nodes Node h = null, t = null; for (E e : c) { diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 514a55f20d7c..9079977b71da 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -265,7 +265,7 @@ boolean casItem(E cmp, E val) { /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedQueue() { + public @Modifiable @IteratorPolyMod ConcurrentLinkedQueue() { head = tail = new Node(); } @@ -278,7 +278,7 @@ boolean casItem(E cmp, E val) { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable ConcurrentLinkedQueue(Collection c) { + public @Modifiable @IteratorPolyMod ConcurrentLinkedQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index fca57cd36cb6..88089e87c66f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -35,7 +35,7 @@ package java.util.concurrent; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -147,7 +147,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentNavigableMap this); /** * Returns a {@link NavigableSet} view of the keys contained in this map. @@ -168,7 +168,7 @@ public interface ConcurrentNavigableMap * @return a navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentNavigableMap this); /** * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. @@ -187,5 +187,5 @@ public interface ConcurrentNavigableMap * @return a reverse order navigable set view of the keys in this map */ @SideEffectFree - @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentNavigableMap this); + @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentNavigableMap this); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 62b7c4986535..424905b57961 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; @@ -1654,14 +1654,14 @@ else if (doRemove(key, v) != null) * @return a navigable set view of the keys in this map */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable ConcurrentSkipListMap this) { KeySet ks; if ((ks = keySet) != null) return ks; return keySet = new KeySet<>(this); @@ -1687,7 +1687,7 @@ else if (doRemove(key, v) != null) * weakly consistent. */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable ConcurrentSkipListMap this) { Values vs; if ((vs = values) != null) return vs; return values = new Values<>(this); @@ -1721,7 +1721,7 @@ else if (doRemove(key, v) != null) * sorted in ascending key order */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable ConcurrentSkipListMap this) { EntrySet es; if ((es = entrySet) != null) return es; return entrySet = new EntrySet(this); @@ -1736,7 +1736,7 @@ else if (doRemove(key, v) != null) } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentSkipListMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet descendingKeySet(@PolyShrinkable ConcurrentSkipListMap this) { return descendingMap().navigableKeySet(); } @@ -3066,35 +3066,35 @@ public Map.Entry pollLastEntry(@Shrinkable SubMap this) { /* ---------------- Submap Views -------------- */ @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet keySet(@PolyShrinkable SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable NavigableSet navigableKeySet(@PolyShrinkable SubMap this) { KeySet ks; if ((ks = keySetView) != null) return ks; return keySetView = new KeySet<>(this); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Collection values(@PolyShrinkable SubMap this) { Values vs; if ((vs = valuesView) != null) return vs; return valuesView = new Values<>(this); } @SideEffectFree - public @IteratorPolyShrinkable @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable SubMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable SubMap this) { EntrySet es; if ((es = entrySetView) != null) return es; return entrySetView = new EntrySet(this); } @SideEffectFree - public @IteratorPolyShrinkable NavigableSet descendingKeySet() { + public @IteratorPolyMod NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index d1435b728f1c..31fda8731889 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -38,7 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -132,7 +132,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet() { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -144,7 +144,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -159,7 +159,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(Collection c) { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -172,7 +172,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(SortedSet s) { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -180,7 +180,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Modifiable @IteratorPolyMod ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -191,7 +191,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable @IteratorPolyShrinkable ConcurrentSkipListSet clone() { + public @Modifiable @IteratorPolyMod ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 64359e6171a2..83abe7bfab5b 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -36,7 +36,7 @@ package java.util.concurrent; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -154,7 +154,7 @@ public class DelayQueue extends AbstractQueue /** * Creates a new {@code DelayQueue} that is initially empty. */ - public @Modifiable @IteratorPolyShrinkable DelayQueue() {} + public @Modifiable @IteratorPolyMod DelayQueue() {} /** * Creates a {@code DelayQueue} initially containing the elements of the @@ -164,7 +164,7 @@ public class DelayQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable DelayQueue(Collection c) { + public @Modifiable @IteratorPolyMod DelayQueue(Collection c) { this.addAll(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 14cfadf8ca79..1e040688930a 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -194,7 +194,7 @@ static final class Node { * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPolyShrinkable LinkedBlockingDeque() { + public @Modifiable @IteratorPolyMod LinkedBlockingDeque() { this(Integer.MAX_VALUE); } @@ -204,7 +204,7 @@ static final class Node { * @param capacity the capacity of this deque * @throws IllegalArgumentException if {@code capacity} is less than 1 */ - public @Modifiable @IteratorPolyShrinkable LinkedBlockingDeque(int capacity) { + public @Modifiable @IteratorPolyMod LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } @@ -219,7 +219,7 @@ static final class Node { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable LinkedBlockingDeque(Collection c) { + public @Modifiable @IteratorPolyMod LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); addAll(c); } 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 3c00956bfb7d..b61bc66101a0 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -264,7 +264,7 @@ void fullyUnlock() { * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ - public @Modifiable @IteratorPolyShrinkable LinkedBlockingQueue() { + public @Modifiable @IteratorPolyMod LinkedBlockingQueue() { this(Integer.MAX_VALUE); } @@ -275,7 +275,7 @@ void fullyUnlock() { * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ - public @Modifiable @IteratorPolyShrinkable LinkedBlockingQueue(int capacity) { + public @Modifiable @IteratorPolyMod LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); @@ -291,7 +291,7 @@ void fullyUnlock() { * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable LinkedBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyMod LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 53994bc0f49e..49a1bbbc0ffe 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -1183,7 +1183,7 @@ else if (s == n) // stale /** * Creates an initially empty {@code LinkedTransferQueue}. */ - public @Modifiable @IteratorPolyShrinkable LinkedTransferQueue() { + public @Modifiable @IteratorPolyMod LinkedTransferQueue() { head = tail = new Node(); } @@ -1196,7 +1196,7 @@ else if (s == n) // stale * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable LinkedTransferQueue(Collection c) { + public @Modifiable @IteratorPolyMod LinkedTransferQueue(Collection c) { Node h = null, t = null; for (E e : c) { Node newNode = new Node(Objects.requireNonNull(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 9deb7bdeccde..ebfd837c2ef8 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -39,7 +39,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; -import org.checkerframework.checker.modifiability.qual.IteratorPolyShrinkable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; @@ -210,7 +210,7 @@ public class PriorityBlockingQueue extends AbstractQueue * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue() { + public @Modifiable @IteratorPolyMod PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } @@ -223,7 +223,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue(int initialCapacity) { + public @Modifiable @IteratorPolyMod PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } @@ -239,7 +239,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ - public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue(int initialCapacity, + public @Modifiable @IteratorPolyMod PriorityBlockingQueue(int initialCapacity, Comparator comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); @@ -263,7 +263,7 @@ public class PriorityBlockingQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyShrinkable PriorityBlockingQueue(Collection c) { + public @Modifiable @IteratorPolyMod PriorityBlockingQueue(Collection c) { boolean heapify = true; // true if not known to be in heap order boolean screen = true; // true if must screen for nulls if (c instanceof SortedSet) { From f210aa52d9b91bd662af5cd43bb9f2a218edeee1 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 31 May 2026 13:31:56 -0700 Subject: [PATCH 101/119] update checker qual. --- checker-qual.jar | Bin 291812 -> 292495 bytes .../modifiability/qual/IteratorPolyMod.java | 27 ++++++++++++++++++ .../qual/IteratorPolyShrinkable.java | 23 --------------- ...inkable.java => MaybeIteratorPolyMod.java} | 4 +-- .../qual/PreservesModifiability.java | 25 ++++++++++++++++ 5 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java delete mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java rename src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/{MaybeIteratorPolyShrinkable.java => MaybeIteratorPolyMod.java} (90%) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java diff --git a/checker-qual.jar b/checker-qual.jar index fbd435a517ff42057757a020a1a2d8e808d055b8..1860c4b7e246d64531c204307d7690e6132758c1 100644 GIT binary patch delta 6777 zcmZu$2{={T7kAD*=IfeWp^zx^tW2Ruh)|LYA!MGL%$k&5XtJ7AG^(U|K&5((nlwp0 z#e0=Xn(!LE{_EUbH@@%R_to+Htzoad)?VxEqi3D+rQPxcN2%}`lI2f^MRijmA~#`M z6g3*Q&7ipX-YHQg@ey+)R!(V3erzV!&}FFdQu}y^nPyp)Z`s}@vdJ<*w!KRGtJhuJ zs1UHa*iiMqPpg|R6ep>k_GoI|P?0_&Gj7rac13uJkyW{_Le!e2#WZc$FH*c0e3^{)8-4YogIj|7QWPLC>RT(|a5$F2&hR3xHZ zE`6QCVreh6nmY$}#Z=$SaKDQ4ikv{!w| zEz!29MuYZIx<`BdewS}kq}1&B?~Los*-LKShZIjv|HZ1+R^qEx{?#k`QRmr1+peUV z4C8AKAqm{xi1tp$%K}q|K;zLxi&lT`sMwH?oMf0^VfxQJH^@EX{@xwE*7Za4bDq2PsRy$z>8e@E?9KYe zN?Yl`s0!OpsbY&Sn12@c_2Mu}A|fZELnsYeX2a4CuGx4pd^sW_9uQGZX~VWiil6V1 z8J!-HnUe0ClDOd4Nm=LL9**lwy$Sa`{KZkixgjWC&nOfy+KWmPFTXd zMOwbm(G^Afobi>-*G1K4Ic7z#%vTKxf+&aRMQa)+PVw^ESnQ*?``L!e&6;tF`_?7; ztWnI&_?UgOR&k7LO@euqMnbpdm=}d*>YIY|wy$yPskJMe^SZSs_h!bMdG%Cg$0fV> zqUWY*MQhbO7!h23`j%5kPB-`H^6-r5OYX!l*N%v!gm&i0#Ge{}VMCCL&j!(58}lD5 zR6puyvTxsxa0RENbBX_mh0U9*HCz6e?Znt@<9V$et0gWyp6k%Acf57vnK|Eb%z~;q zHm3gDooaI2VcFTL)YC4f{GB9Zixd}si=JEZz+l&r`X~+ePM4Fd5wrWAm$`nlTE1m= zsh@1#wly7@s_q_Ep&4)UBr5{GEr>kf60rL(1=VpEuZ5JX*1Dv(b9+Q%{Lmbc6QSW$ znVi)A9ks7FW5Iej;HOCGfHTD?=KH2cXGEvZjn2SQ#l^%$M8+k?WiAl3cg2*@l*eY= zoKLk{2f^m$J2AZruoAw5v>7dw#LW!uM}?6DDJBHdcgGsbAE- zR;RPqCS&;4!sV6{Y@w#}vcjkM&#@t^E2=N~q#Y14XBx_Qk0my16~Rjj%3G%s?| z&@p1A`mI%MLz%l1c*`IDvuE!__x9%ID~AHF?%wn{t6{ZDMF`ViD}Cj$qTdTe7h| zP4lk|&aKC9_(e}sDf~;Hc$&(o_Mmp0SYF35bCnSeY(_-H6)ye9@us~~preJO0v10w zYIJ1?Xj9B+Sn`82RAW#Ni~Rnxqwsi`K#e!Jn+1N>X)$W_`f%drU^pcUb)t;iy4A>T zjU?=eNJgC)A-#QA|hVD zqQK{lLbWu3vC{wR6VT=|eAtbCXw3|=hH=_2_sR^?B6Gl;VG`(n<`VI3h8aVL%_qP? zl(D7lvIq#xqPTEOlrg0z=Li`UFcD)6=(Tx-`9q9xpfd{y_%6oS)4>Z_pat)x7zv1! zM%~Ka3=itX8GZWAZ$<|C3Mf7pNTA}-6+%-P&|6Na0#6z-5wgJUs zMv;BA34k%wvzr=K$x4i2T@{wtc`GFf{alQ7M%AD?|FJ`;r2@c3yV`2PyyxN;=ISjHQns0T+3Uq@0INz6*dcykmj;QC4CMzK1Dw zc&&&*WXR%%3r`5>a(PA^Oyn3bxGIa4jIAHUj;6Ps{YCKLxgw(sC*;uh!-Ze06RmoU z{W+4}e}jEmLVXh@4Gn6zPVtRFn{BuyFaie!#)(e6OTbhR!-GUG^peL0xn!8jGhoDO{k13zjkZF4U2Mv1*JR-PAvrk%lMVux_;%FyGhJaQ)^V0~A{O zu?KzFn!c~&aG}(k;nDLcNYiCB;lCf4?HqMnrT#a=h0gCBS@>HWJ#lEEq6Vmkp%V`c zq~jPN&4n@ztmSkuAtMc83@ruy8tAr3VgNm5CCy=io`Hgm6m}Nd0Lbx zZ&IQM4*VM`1GKhk;UT-HDr97#TLm{Tifwu;ZCoTqO(@fbt=bsOY7N4?)1W1Q8qQeK z&xZ*aK4cF^ol{zbd7?%0;mvTyl)49%I*chGVaU3XgO|exMWv?8T9|^<2!;nwQI(!M zQpkAFhxCPj2iHc@iqLcqOa6KUHjM_P>M~|9(twsD8}>9B;XxbA=uH*s z$b+2;X8r550gQM6%>xe;T;op@T;o}gKvr(bOroC$3-$Q$If&+xSDv7Y3;eK)KZk<6 z8NN53o8mfS!&neVFBd#bV7(bGB^%C?#^vTXf{sTBeulF%aYe27L-S4y0hX4G6>S|$fPD<+VY4L~mc$X} zqa_-4#}nXVg}LAwV+;(>u=^oy<)o%nfV2#P3$W=9*y1u)i-n9RI4#801s=aF8syP% z=>RR8#kg+19U9MHM(Dhy*n5Iw*HSddPO_LN$S%VSjnTpi2HNA9iCIDD3VX(!>H%{H zOz&5FtaxMz5rjBkPTEQdILU$qt5{$N1*NnYs5@fSMa#!BMv(4^!jiSD&_ z&VmrS7znvyENb+xC*ajs%);D_EHHqHPAEy(Ou!B&eATLNA%Jp5uzV{4r4=|@W1Vro zN_fp;4UrKA&8-;8RhHgcMd*XuaI}teL1r}Gv{=Pl7xZ&}CjpOK7z^5RHvwbDA=tHt zfc?ABaLYI}wBAb?`#m(bd^{3$cqwB&HCE$lAuKZyZ)Pmxvk#e*EYo=a3SF6DK)WK) zsb#@P2w*|108FC~3!X+$SA!#1)eR*jhgmfvNOi;3s5vSGqVU8G4_wD_!n`_)wVpfy z4d$OBOu-2(rQnPRn(^iYZ0pK;RyGV|&*BW_xuf>G-wYp8SY}*ATH7&Ee@JOjykw;>6V(f!93(s=aXxnBsMlb#HqgXR~02 zTl?UqbXvjBhl!={J|f~Dk7#jt@55M8eXwdW-nQi~VCs=ofa^WD1Lqs~ZR+?GwEfUm z<75nKxd2##rZ0j=KS7=^j+T=htePdf@x^f4pRpi`mg$5_f1JH1{ZM_102srI@90|F zALH5blZp4o4eWo->dvOsx?xoyqXWiM&?Z;_^kE?jssz9cp0MD(09b?5R0QMSvNrax zYbq|D`H0*A?y#_LlAk~W%eBzIT1NsJ4 z@aiXG(cXuxBRGz80&y3^zOZx(9r_iTgP0MZHytC|DggSB&4L#{!R_g|u2Da$rVj`t zz%B@rUj(;0XW-ZT zB%p$^Rj(B9@Pa&8M;1iisDC105tFa)AuF!yvP$r7D*JPgtkQRpT zlo)LS5;Zw^d5y(ljCKN=Vc!a6YfCsw990gE0hr8;D zz@U0;2FR=;+2*q)%(l@SK5U3Y`$C5SI zBkU3|dZZzgqi`A139L>8E#b*N^`I^aBOU8afU_58Bz$Yakd99tRF0Q^MB(*h4v!@A zP&7I_H=HE3I#f6cuG_(_xAmJ-{u0+W0K=7=SMG!USHCf`p8;+Wmitorgzl^-+z(| zTYmD;Ple&Mqb1O8%z#IaZqK<}FnmjPm4&CL&)Ow5mmXaEJhmtJa`vfFEpx9fcF*-N za+rNRpfp@BYXAM!VNpi=((OK-^Ke`OSbH7 z`oj`Dm1c(oXBmW*^z6$2q8^%Hx_Fs^Uu*J}h1Wpu)Q{(HB-b|YYWryQzQ=9DRE>2} z+eD;ohNjxg{7?m|pnP!q3srZQ%(#}s$96XlpI4~8Fm1+I`QT#G;WQ(xp|QHKB&@<= z`rzYn;CbgbGzJsoV2O8)q5rH>|uhQtwb%m7d3s8S*_dc`sVq^C>cyR?yK+`!Jy}(_ zmm)biACTv$@76SG07)FxB@tmzL8%Sf*dIAML|@o-R8N=d`?IewGeSzs9|83j3biG# zHVal)GIbjR&D%LKyimbJW!o7uS(Vz6yj=`@uS%Us@NQ_-#{Do*!?3DiUfaj0!d#yD zvyah-f(ou56sTh_cJ7l|@U%TbBwvztPynh>szx2ixI0Z>?{O~;bMcX=j>TzbeX{*O6LNYTLxoE}4TkH`S> zUvr8uau{~I+y>8WK`$MtN7X=Y5H%%N`-Eb6Fo=pFOOFl&g=aE*bLNQ!%+YsN?xlFx!yNoB}xNW6C{!j4Hb$PM>9Bzmyg{)2B|{TF}tP zlahuy82T@#3|$xTYGn_>-fj9K#8-uLL#R6$_mweL22>u5hhoO1eT)j^4aNRmkY>CI z!4Y79MP^eXJqJt)R2brL#7L9KASwW5*lmEfbFI7-^REHUgp~?XjEXYRU}0O@uo2Uh zcv~O=CFmGQEm`HZ!?1+My-eOPI+2`IVdm~(xEEP!3`|fXN}!-gwBYVdEPT~)^ctkW z+pNG~Fj0Z30i++y@xv1CYRi1vRWF%&p zq08Is;mAll*!%T)kjCY}Lq2oCC_0tf0s;6Bs2bsoZXXWEjM0#5M8^~RQ4D-GC1Pkc z#$G5IW3mOt0zC|r+prolbD0(2Gvx(|oC{PNQ)}=sp%aL?6`$A=elWqNR9Oo^2`o)9 zZ>kMrcA4TG9&N`!e>1$p`yCjta>A-sn_>O~j*PK(`Cpx-<7M*uIx~UaXsmdi3%njp z9pKDp92IL^d5}W9CxC_pHG?8^j8`H7)=;W}clWJ1w(Nm~Ng%Bgp~C{d7S$Hiig-`q zK{9^E9$H{K{k(}9G>yUi>Nia$dz}|^@|;Fgwpn5P-M)M>D+sm1KDhZaaLo#*P+$Om zpbWtAVwgAlA=1 zd%8eIupbe@hS>ob^txg#z`DT{&PMMM=8ov0bt4Xut? zLX;EEk=!NB+Q5Uhr3@H4W1D=IF|fiJTUwpRz;kCTTd{zFjmvR%Ne)t?3ub>)$ml8; zyy-8#5j6cke>}z;w~{dh_$ zqbnvHzK+rT-LTBE^$f)Fz;Po3=iJcyVle~y6A<{7Fpz_Qy92M?_(p6a{o(!uJPqDk znY9J5uP*M$)Nf-X986yUIiNC$RzVCh9#BI&2Ai>8z+ zFA@(+@IWc1D-v&g;vmNSr7Kc~s3^=DuFII(C^Uc4XQ03U&8tIk9@t0Y2sMJ&QTQ$^ zjHcu9_i#Woer}&dV-3F#=jEfpF9zS>#UptT%`JrD7!(YN#iM3!!gD%cI9j9#i(@g} z{9fjvqeu;YiN$w$WuL}?T{!1B8~}fq3$9|wjl*wSjja^(AP&!MiUVUXm=6EcQ-`2< zbai)<5^jyhOZ}6Z6!T9!zPXbpLE%C=3?k;@q7F-d5mfV_s~3=Y*pSN}yvzu^y+va7 z3+J18nBiY(&3HZ}>e*%spn_z))BdL-{@duHH_H>_q^8Ek6wQw!m)6;TtPfz3j-O2qIn@11L diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java new file mode 100644 index 000000000000..ec4c8d2b8de1 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java @@ -0,0 +1,27 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} and {@code + * listIterator()} methods preserves the ability to call modification methods in its iterator. + * + *

For example, if collection {@code c} has type {@code @Shrinkable}, then {@code c.iterator()} + * also has type {@code @Shrinkable}. If list {@code l} has type {@code @Replaceable}, then {@code + * l.listIterator()} also has type {@code @Replaceable}. For any collection whose type is + * {@code @MaybeIteratorPolyMod}, its iterator is always {@code @MaybeShrinkable}. + * + *

This annotation is used in GrowChecker, ShrinkChecker, and ReplaceChecker. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(MaybeIteratorPolyMod.class) +public @interface IteratorPolyMod {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java deleted file mode 100644 index fb4fd4ea8528..000000000000 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyShrinkable.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.checkerframework.checker.modifiability.qual; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.checkerframework.framework.qual.SubtypeOf; - -/** - * If a collection's type is {@code @IteratorPolyShrinkable}, then its {@code iterator()} method preserves - * the ability to call {@code Iterator.remove()}. That is, if collection {@code c} has type - * {@code @Shrinkable}, then {@code c.iterator()} also has type {@code @Shrinkable}. For any - * collection whose type is {@code @MaybeIteratorPolyShrinkable}, its iterator is always - * {@code @Unshrinkable}. - * - * @checker_framework.manual #modifiability-checker Modifiability Checker - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@SubtypeOf(MaybeIteratorPolyShrinkable.class) -public @interface IteratorPolyShrinkable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyShrinkable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java similarity index 90% rename from src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyShrinkable.java rename to src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java index e48346a6d48d..f113fdc671f6 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyShrinkable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java @@ -13,7 +13,7 @@ * *

This is the default qualifier for unannotated types. * - * @see IteratorPolyShrinkable + * @see IteratorPolyMod * @checker_framework.manual #modifiability-checker Modifiability Checker */ @Documented @@ -21,4 +21,4 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf({}) @DefaultQualifierInHierarchy -public @interface MaybeIteratorPolyShrinkable {} +public @interface MaybeIteratorPolyMod {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java new file mode 100644 index 000000000000..5bbcc4f6e677 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The annotated method preserves modifiability capabilities from its first argument to its return + * value. + * + *

For example, if the first argument is {@code @Modifiable} or {@code @IteratorPolyMod}, then + * the return type is also {@code @Modifiable} or {@code @IteratorPolyMod}. If the first argument is + * anything other than {@code @Modifiable} or {@code @IteratorPolyMod}, then the return type is the + * top {@code @MaybeModifiable}. + * + *

If the annotated method has no parameters, then this annotation has no effect on the method. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface PreservesModifiability {} From 28addfae749e1fabe0ec71444f32573e1a5312c2 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Jun 2026 13:03:28 -0700 Subject: [PATCH 102/119] annotated @SeqGrowable on addFirst and addLast. --- .../share/classes/java/util/ArrayDeque.java | 11 +++++----- .../share/classes/java/util/ArrayList.java | 5 +++-- .../share/classes/java/util/Deque.java | 11 +++++----- .../classes/java/util/LinkedHashMap.java | 4 ++++ .../classes/java/util/LinkedHashSet.java | 11 +++++----- .../share/classes/java/util/LinkedList.java | 21 ++++++++++--------- .../share/classes/java/util/List.java | 5 +++-- .../java/util/SequencedCollection.java | 6 +++--- .../share/classes/java/util/SortedSet.java | 8 ++++--- .../share/classes/java/util/TreeSet.java | 15 ++++++------- .../java/util/concurrent/BlockingDeque.java | 19 +++++++++-------- .../concurrent/ConcurrentLinkedDeque.java | 11 +++++----- .../concurrent/ConcurrentSkipListSet.java | 17 ++++++++------- .../util/concurrent/CopyOnWriteArrayList.java | 13 ++++++------ .../util/concurrent/LinkedBlockingDeque.java | 19 +++++++++-------- 15 files changed, 97 insertions(+), 79 deletions(-) diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index df6f3a597294..612c48fbdc30 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -42,6 +42,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -310,7 +311,7 @@ static final E nonNullElementAt(@PolyNull @PolySigned Object[] es, int i) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { + public void addFirst(@SeqGrowable @GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); final Object[] es = elements; @@ -330,7 +331,7 @@ public void addFirst(@Growable @GuardSatisfied ArrayDeque this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable @GuardSatisfied ArrayDeque this, E e) { + public void addLast(@SeqGrowable @GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); final Object[] es = elements; @@ -372,7 +373,7 @@ private void copyElements(Collection c) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable ArrayDeque this, E e) { + public boolean offerFirst(@SeqGrowable ArrayDeque this, E e) { addFirst(e); return true; } @@ -386,7 +387,7 @@ public boolean offerFirst(@Growable ArrayDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable ArrayDeque this, E e) { + public boolean offerLast(@SeqGrowable ArrayDeque this, E e) { addLast(e); return true; } @@ -644,7 +645,7 @@ public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable @GuardSatisfied ArrayDeque this, E e) { + public void push(@SeqGrowable @GuardSatisfied ArrayDeque this, E e) { addFirst(e); } diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index dd0a291b1960..416d51738c60 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -35,6 +35,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -593,7 +594,7 @@ public void add(@Growable @GuardSatisfied ArrayList this, @NonNegative int in @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable ArrayList this, E element) { + public void addFirst(@SeqGrowable ArrayList this, E element) { add(0, element); } @@ -605,7 +606,7 @@ public void addFirst(@Growable ArrayList this, E element) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable ArrayList this, E element) { + public void addLast(@SeqGrowable ArrayList this, E element) { add(element); } diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 413f1c10a16e..9a1521435691 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -41,6 +41,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -243,7 +244,7 @@ public interface Deque extends Queue, SequencedCollection { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void addFirst(@Growable @GuardSatisfied Deque this, E e); + void addFirst(@SeqGrowable @GuardSatisfied Deque this, E e); /** * Inserts the specified element at the end of this deque if it is * possible to do so immediately without violating capacity restrictions, @@ -266,7 +267,7 @@ public interface Deque extends Queue, SequencedCollection { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void addLast(@Growable @GuardSatisfied Deque this, E e); + void addLast(@SeqGrowable @GuardSatisfied Deque this, E e); /** * Inserts the specified element at the front of this deque unless it would * violate capacity restrictions. When using a capacity-restricted deque, @@ -285,7 +286,7 @@ public interface Deque extends Queue, SequencedCollection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean offerFirst(@Growable Deque this, E e); + boolean offerFirst(@SeqGrowable Deque this, E e); /** * Inserts the specified element at the end of this deque unless it would * violate capacity restrictions. When using a capacity-restricted deque, @@ -304,7 +305,7 @@ public interface Deque extends Queue, SequencedCollection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean offerLast(@Growable Deque this, E e); + boolean offerLast(@SeqGrowable Deque this, E e); /** * Retrieves and removes the first element of this deque. This method * differs from {@link #pollFirst pollFirst} only in that it throws an @@ -583,7 +584,7 @@ public interface Deque extends Queue, SequencedCollection { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void push(@Growable @GuardSatisfied Deque this, E e); + void push(@SeqGrowable @GuardSatisfied Deque this, E e); /** * Pops an element from the stack represented by this deque. In other * words, removes and returns the first element of this deque. diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 2dff6128f0f6..443bcefe7b22 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -728,6 +729,7 @@ final T[] valuesToArray(T[] a, boolean reversed) { return a; } + @SeqUngrowable final class LinkedKeySet extends AbstractSet implements SequencedSet { final boolean reversed; LinkedKeySet(boolean reversed) { this.reversed = reversed; } @@ -854,6 +856,7 @@ public SequencedSet reversed() { } } + @SeqUngrowable final class LinkedValues extends AbstractCollection implements SequencedCollection { final boolean reversed; LinkedValues(boolean reversed) { this.reversed = reversed; } @@ -975,6 +978,7 @@ public SequencedCollection reversed() { } } + @SeqUngrowable final class LinkedEntrySet extends AbstractSet> implements SequencedSet> { final boolean reversed; diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index b0cd7488430c..20b29b39da0a 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -236,7 +237,7 @@ public Spliterator spliterator() { * @throws IllegalArgumentException if numElements is negative * @since 19 */ - public static LinkedHashSet newLinkedHashSet(int numElements) { + public static @Modifiable LinkedHashSet newLinkedHashSet(int numElements) { if (numElements < 0) { throw new IllegalArgumentException("Negative number of elements: " + numElements); } @@ -260,7 +261,7 @@ LinkedHashMap map() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable LinkedHashSet this, E e) { + public void addFirst(@SeqGrowable LinkedHashSet this, E e) { map().putFirst(e, PRESENT); } @@ -275,7 +276,7 @@ public void addFirst(@Growable LinkedHashSet this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable LinkedHashSet this, E e) { + public void addLast(@SeqGrowable LinkedHashSet this, E e) { map().putLast(e, PRESENT); } @@ -345,8 +346,8 @@ class ReverseLinkedHashSetView extends AbstractSet implements SequencedSet @SideEffectFree public Iterator iterator() { return map().sequencedKeySet().reversed().iterator(); } public boolean add(@Growable ReverseLinkedHashSetView this, E e) { return LinkedHashSet.this.add(e); } - public void addFirst(@Growable ReverseLinkedHashSetView this, E e) { LinkedHashSet.this.addLast(e); } - public void addLast(@Growable ReverseLinkedHashSetView this, E e) { LinkedHashSet.this.addFirst(e); } + public void addFirst(@SeqGrowable ReverseLinkedHashSetView this, E e) { LinkedHashSet.this.addLast(e); } + public void addLast(@SeqGrowable ReverseLinkedHashSetView this, E e) { LinkedHashSet.this.addFirst(e); } @Pure public E getFirst() { return LinkedHashSet.this.getLast(); } @Pure diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index f8ee1602669f..440ad36f6f67 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -36,6 +36,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -341,7 +342,7 @@ public E removeLast(@Shrinkable @GuardSatisfied @NonEmpty @CanShrink LinkedList< @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { + public void addFirst(@SeqGrowable @GuardSatisfied LinkedList this, E e) { linkFirst(e); } @@ -355,7 +356,7 @@ public void addFirst(@Growable @GuardSatisfied LinkedList this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable @GuardSatisfied LinkedList this, E e) { + public void addLast(@SeqGrowable @GuardSatisfied LinkedList this, E e) { linkLast(e); } @@ -798,7 +799,7 @@ public boolean offer(@Growable LinkedList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable LinkedList this, E e) { + public boolean offerFirst(@SeqGrowable LinkedList this, E e) { addFirst(e); return true; } @@ -812,7 +813,7 @@ public boolean offerFirst(@Growable LinkedList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable LinkedList this, E e) { + public boolean offerLast(@SeqGrowable LinkedList this, E e) { addLast(e); return true; } @@ -886,7 +887,7 @@ public boolean offerLast(@Growable LinkedList this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable @GuardSatisfied LinkedList this, E e) { + public void push(@SeqGrowable @GuardSatisfied LinkedList this, E e) { addFirst(e); } @@ -1554,7 +1555,7 @@ public E pop() { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(E e) { + public void push(@SeqGrowable ReverseOrderLinkedListView this, E e) { rdeque.push(e); } @@ -1582,13 +1583,13 @@ public E peekFirst() { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(E e) { + public boolean offerLast(@SeqGrowable ReverseOrderLinkedListView this, E e) { return rdeque.offerLast(e); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(E e) { + public boolean offerFirst(@SeqGrowable ReverseOrderLinkedListView this, E e) { return rdeque.offerFirst(e); } @@ -1698,13 +1699,13 @@ public boolean contains(Object o) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(E e) { + public void addLast(@SeqGrowable ReverseOrderLinkedListView this, E e) { rdeque.addLast(e); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(E e) { + public void addFirst(@SeqGrowable ReverseOrderLinkedListView this, E e) { rdeque.addFirst(e); } diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index e0faf2f7f340..80328ab47f7a 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -39,6 +39,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -873,7 +874,7 @@ default Spliterator spliterator() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addFirst(@Growable List this, E e) { + default void addFirst(@SeqGrowable List this, E e) { this.add(0, e); } @@ -890,7 +891,7 @@ default void addFirst(@Growable List this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addLast(@Growable List this, E e) { + default void addLast(@SeqGrowable List this, E e) { this.add(e); } diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 2bfbc7336e52..d3ddf4bcceca 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -25,8 +25,8 @@ package java.util; -import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.dataflow.qual.Pure; @@ -115,7 +115,7 @@ public interface SequencedCollection extends Collection { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addFirst(@Growable SequencedCollection this, E e) { + default void addFirst(@SeqGrowable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } @@ -136,7 +136,7 @@ default void addFirst(@Growable SequencedCollection this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default void addLast(@Growable SequencedCollection this, E e) { + default void addLast(@SeqGrowable SequencedCollection this, E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 988996877d9c..5478da47d74b 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -27,6 +27,8 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -120,7 +122,7 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public interface SortedSet extends Set, SequencedSet { +public @SeqUngrowable interface SortedSet extends Set, SequencedSet { /** * Returns the comparator used to order the elements in this set, * or {@code null} if this set uses the {@linkplain Comparable @@ -302,7 +304,7 @@ public Comparator getComparator() { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - default void addFirst(E e) { + default void addFirst(@SeqGrowable SortedSet this, E e) { throw new UnsupportedOperationException(); } @@ -321,7 +323,7 @@ default void addFirst(E e) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - default void addLast(E e) { + default void addLast(@SeqGrowable SortedSet this, E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 0b5a0ab42538..d9784f533b62 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -30,8 +30,9 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -117,7 +118,7 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness", "modifiability"}) -public class TreeSet extends AbstractSet +public @SeqUngrowable class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { /** @@ -148,7 +149,7 @@ public class TreeSet extends AbstractSet * integers), the {@code add} call will throw a * {@code ClassCastException}. */ - public @Modifiable @IteratorPolyMod TreeSet() { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod TreeSet() { this(new TreeMap<>()); } @@ -165,7 +166,7 @@ public class TreeSet extends AbstractSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyMod TreeSet(@Nullable Comparator comparator) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod TreeSet(@Nullable Comparator comparator) { this(new TreeMap<>(comparator)); } @@ -183,7 +184,7 @@ public class TreeSet extends AbstractSet * not {@link Comparable}, or are not mutually comparable * @throws NullPointerException if the specified collection is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty Collection c) { this(); addAll(c); } @@ -195,7 +196,7 @@ public class TreeSet extends AbstractSet * @param s sorted set whose elements will comprise the new set * @throws NullPointerException if the specified sorted set is null */ - public @Modifiable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod @PolyNonEmpty TreeSet(@PolyNonEmpty SortedSet s) { this(s.comparator()); addAll(s); } @@ -565,7 +566,7 @@ public void addLast(E e) { */ @SideEffectFree @SuppressWarnings("unchecked") - public @Modifiable @IteratorPolyMod Object clone(@GuardSatisfied TreeSet this) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod Object clone(@GuardSatisfied TreeSet this) { TreeSet clone; try { clone = (TreeSet) super.clone(); diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java index 83e96170b34e..8e646e55a116 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java @@ -41,6 +41,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -239,7 +240,7 @@ public interface BlockingDeque extends BlockingQueue< @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void addFirst(@Growable BlockingDeque this, E e); + void addFirst(@SeqGrowable BlockingDeque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -257,7 +258,7 @@ public interface BlockingDeque extends BlockingQueue< @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void addLast(@Growable BlockingDeque this, E e); + void addLast(@SeqGrowable BlockingDeque this, E e); /** * Inserts the specified element at the front of this deque if it is @@ -275,7 +276,7 @@ public interface BlockingDeque extends BlockingQueue< */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean offerFirst(@Growable BlockingDeque this, E e); + boolean offerFirst(@SeqGrowable BlockingDeque this, E e); /** * Inserts the specified element at the end of this deque if it is @@ -293,7 +294,7 @@ public interface BlockingDeque extends BlockingQueue< */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean offerLast(@Growable BlockingDeque this, E e); + boolean offerLast(@SeqGrowable BlockingDeque this, E e); /** * Inserts the specified element at the front of this deque, @@ -309,7 +310,7 @@ public interface BlockingDeque extends BlockingQueue< */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void putFirst(@Growable BlockingDeque this, E e) throws InterruptedException; + void putFirst(@SeqGrowable BlockingDeque this, E e) throws InterruptedException; /** * Inserts the specified element at the end of this deque, @@ -325,7 +326,7 @@ public interface BlockingDeque extends BlockingQueue< */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void putLast(@Growable BlockingDeque this, E e) throws InterruptedException; + void putLast(@SeqGrowable BlockingDeque this, E e) throws InterruptedException; /** * Inserts the specified element at the front of this deque, @@ -348,7 +349,7 @@ public interface BlockingDeque extends BlockingQueue< */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean offerFirst(@Growable BlockingDeque this, E e, long timeout, TimeUnit unit) + boolean offerFirst(@SeqGrowable BlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -372,7 +373,7 @@ boolean offerFirst(@Growable BlockingDeque this, E e, long timeout, TimeUnit */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - boolean offerLast(@Growable BlockingDeque this, E e, long timeout, TimeUnit unit) + boolean offerLast(@SeqGrowable BlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException; /** @@ -722,5 +723,5 @@ boolean offer(@Growable BlockingDeque this, E e, long timeout, TimeUnit unit) */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void push(@Growable BlockingDeque this, E e); + void push(@SeqGrowable BlockingDeque this, E e); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index c69000e14e8c..cf6fbee91ae1 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -42,6 +42,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -851,7 +852,7 @@ private void initHeadTail(Node h, Node t) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { + public void addFirst(@SeqGrowable ConcurrentLinkedDeque this, E e) { linkFirst(e); } @@ -867,7 +868,7 @@ public void addFirst(@Growable ConcurrentLinkedDeque this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable ConcurrentLinkedDeque this, E e) { + public void addLast(@SeqGrowable ConcurrentLinkedDeque this, E e) { linkLast(e); } @@ -880,7 +881,7 @@ public void addLast(@Growable ConcurrentLinkedDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { + public boolean offerFirst(@SeqGrowable ConcurrentLinkedDeque this, E e) { linkFirst(e); return true; } @@ -896,7 +897,7 @@ public boolean offerFirst(@Growable ConcurrentLinkedDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable ConcurrentLinkedDeque this, E e) { + public boolean offerLast(@SeqGrowable ConcurrentLinkedDeque this, E e) { linkLast(e); return true; } @@ -1073,7 +1074,7 @@ public boolean add(@Growable ConcurrentLinkedDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable ConcurrentLinkedDeque this, E e) { addFirst(e); } + public void push(@SeqGrowable ConcurrentLinkedDeque this, E e) { addFirst(e); } /** * Removes the first occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 31fda8731889..3d04502dac72 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -39,8 +39,9 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -114,7 +115,7 @@ * @since 1.6 */ @AnnotatedFor({"nullness", "modifiability"}) -public class ConcurrentSkipListSet +public @SeqUngrowable class ConcurrentSkipListSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable { @@ -132,7 +133,7 @@ public class ConcurrentSkipListSet * Constructs a new, empty set that orders its elements according to * their {@linkplain Comparable natural ordering}. */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet() { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod ConcurrentSkipListSet() { m = new ConcurrentSkipListMap(); } @@ -144,7 +145,7 @@ public class ConcurrentSkipListSet * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(@Nullable Comparator comparator) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod ConcurrentSkipListSet(@Nullable Comparator comparator) { m = new ConcurrentSkipListMap(comparator); } @@ -159,7 +160,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified collection or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(Collection c) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod ConcurrentSkipListSet(Collection c) { m = new ConcurrentSkipListMap(); addAll(c); } @@ -172,7 +173,7 @@ public class ConcurrentSkipListSet * @throws NullPointerException if the specified sorted set or any * of its elements are null */ - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet(SortedSet s) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap(s.comparator()); addAll(s); } @@ -180,7 +181,7 @@ public class ConcurrentSkipListSet /** * For use by submaps */ - @Modifiable @IteratorPolyMod ConcurrentSkipListSet(ConcurrentNavigableMap m) { + @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } @@ -191,7 +192,7 @@ public class ConcurrentSkipListSet * @return a shallow copy of this set */ @SideEffectFree - public @Modifiable @IteratorPolyMod ConcurrentSkipListSet clone() { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = 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 f6b4be48d157..2f91762d334a 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -41,6 +41,7 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; @@ -562,7 +563,7 @@ public void add(@Growable CopyOnWriteArrayList this, int index, E element) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable CopyOnWriteArrayList this, E e) { + public void addFirst(@SeqGrowable CopyOnWriteArrayList this, E e) { add(0, e); } @@ -574,7 +575,7 @@ public void addFirst(@Growable CopyOnWriteArrayList this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable CopyOnWriteArrayList this, E e) { + public void addLast(@SeqGrowable CopyOnWriteArrayList this, E e) { synchronized (lock) { add(getArray().length, e); } @@ -1628,13 +1629,13 @@ public void add(int index, E element) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(E e) { + public void addFirst(@SeqGrowable COWSubList this, E e) { add(0, e); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(E e) { + public void addLast(@SeqGrowable COWSubList this, E e) { synchronized (lock) { add(size, e); } @@ -2176,13 +2177,13 @@ public void add(int index, E element) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(E e) { + public void addFirst(@SeqGrowable Reversed this, E e) { base.add(e); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(E e) { + public void addLast(@SeqGrowable Reversed this, E e) { base.add(0, e); } 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 1e040688930a..2403fd060e11 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -42,6 +42,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -341,7 +342,7 @@ void unlink(@CanShrink LinkedBlockingDeque this, Node x) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(@Growable LinkedBlockingDeque this, E e) { + public void addFirst(@SeqGrowable LinkedBlockingDeque this, E e) { if (!offerFirst(e)) throw new IllegalStateException("Deque full"); } @@ -353,7 +354,7 @@ public void addFirst(@Growable LinkedBlockingDeque this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(@Growable LinkedBlockingDeque this, E e) { + public void addLast(@SeqGrowable LinkedBlockingDeque this, E e) { if (!offerLast(e)) throw new IllegalStateException("Deque full"); } @@ -363,7 +364,7 @@ public void addLast(@Growable LinkedBlockingDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { + public boolean offerFirst(@SeqGrowable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -380,7 +381,7 @@ public boolean offerFirst(@Growable LinkedBlockingDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { + public boolean offerLast(@SeqGrowable LinkedBlockingDeque this, E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -398,7 +399,7 @@ public boolean offerLast(@Growable LinkedBlockingDeque this, E e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putFirst(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { + public void putFirst(@SeqGrowable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -417,7 +418,7 @@ public void putFirst(@Growable LinkedBlockingDeque this, E e) throws Interrup */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void putLast(@Growable LinkedBlockingDeque this, E e) throws InterruptedException { + public void putLast(@SeqGrowable LinkedBlockingDeque this, E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); final ReentrantLock lock = this.lock; @@ -436,7 +437,7 @@ public void putLast(@Growable LinkedBlockingDeque this, E e) throws Interrupt */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerFirst(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { + public boolean offerFirst(@SeqGrowable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); long nanos = unit.toNanos(timeout); @@ -460,7 +461,7 @@ public boolean offerFirst(@Growable LinkedBlockingDeque this, E e, long timeo */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public boolean offerLast(@Growable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { + public boolean offerLast(@SeqGrowable LinkedBlockingDeque this, E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); long nanos = unit.toNanos(timeout); @@ -846,7 +847,7 @@ public int drainTo(@Shrinkable @GuardSatisfied @CanShrink LinkedBlockingDeque */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void push(@Growable LinkedBlockingDeque this, E e) { + public void push(@SeqGrowable LinkedBlockingDeque this, E e) { addFirst(e); } From 6c78df04178bedc06337bcdd0adcfe81465941d7 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Jun 2026 14:19:47 -0700 Subject: [PATCH 103/119] annotated addFirst addLast in TreeSet and ConcurrentSkipListSet. --- src/java.base/share/classes/java/util/TreeSet.java | 5 +++-- .../classes/java/util/concurrent/ConcurrentSkipListSet.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index d9784f533b62..5bc8b3b2289b 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; @@ -538,7 +539,7 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - public void addFirst(E e) { + public void addFirst(@SeqGrowable TreeSet this, E e) { throw new UnsupportedOperationException(); } @@ -554,7 +555,7 @@ public void addFirst(E e) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - public void addLast(E e) { + public void addLast(@SeqGrowable TreeSet this, E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 3d04502dac72..1e39664685f3 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -41,6 +41,7 @@ import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; @@ -467,7 +468,7 @@ public E last(@NonEmpty ConcurrentSkipListSet this) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addFirst(E e) { + public void addFirst(@SeqGrowable ConcurrentSkipListSet this, E e) { throw new UnsupportedOperationException(); } @@ -483,7 +484,7 @@ public void addFirst(E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public void addLast(E e) { + public void addLast(@SeqGrowable ConcurrentSkipListSet this, E e) { throw new UnsupportedOperationException(); } From 5015093e694f0f9ba272fec6e19e69e6a580d531 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Jun 2026 15:01:58 -0700 Subject: [PATCH 104/119] update checker qual --- checker-qual.jar | Bin 292495 -> 295543 bytes .../modifiability/qual/BottomSeqGrowable.java | 21 ++++++++++++++ .../modifiability/qual/MaybeSeqGrowable.java | 26 ++++++++++++++++++ .../modifiability/qual/Modifiable.java | 8 +++--- .../modifiability/qual/PolyModifiable.java | 5 ++-- .../modifiability/qual/PolySeqGrowable.java | 20 ++++++++++++++ .../modifiability/qual/SeqGrowable.java | 23 ++++++++++++++++ .../modifiability/qual/SeqUngrowable.java | 23 ++++++++++++++++ 8 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/BottomSeqGrowable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolySeqGrowable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java diff --git a/checker-qual.jar b/checker-qual.jar index 1860c4b7e246d64531c204307d7690e6132758c1..0608bc8a10e7c1cced15971f9d33a111408de6c8 100644 GIT binary patch delta 8776 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 should rarely write this qualifier. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({SeqGrowable.class, SeqUngrowable.class}) +public @interface BottomSeqGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java new file mode 100644 index 000000000000..edc800772346 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java @@ -0,0 +1,26 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * The top qualifier in the sequenced-grow hierarchy. The collection may or may not support + * positional grow operations such as {@code addFirst} and {@code addLast}. The checker + * conservatively issues an error wherever a sequenced-grow operation is called on a + * {@code @MaybeSeqGrowable} expression. + * + *

This is the default qualifier for unannotated types in the sequenced-grow hierarchy. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({}) +@DefaultQualifierInHierarchy +public @interface MaybeSeqGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java index 6ea06c0065be..978239c8b045 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Modifiable.java @@ -7,13 +7,13 @@ import java.lang.annotation.Target; /** - * Convenience alias usually meaning {@code @Growable @Shrinkable @Replaceable}. Calling a mutating - * operation (growing, shrinking, or replacing) on this collection will not throw {@link - * UnsupportedOperationException}. + * Convenience alias usually meaning {@code @Growable @Shrinkable @Replaceable @SeqGrowable}. + * Calling a mutating operation (growing, shrinking, replacing, or sequenced-growing) on this + * collection will not throw {@link UnsupportedOperationException}. * *

As an exception, {@code @Modifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Modifiable Iterator} means - * {@code @MaybeGrowable @Shrinkable @MaybeReplaceable Iterator}. + * {@code @MaybeGrowable @Shrinkable @MaybeReplaceable @MaybeSeqGrowable Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 5176b1123f9d..83724f7d4be5 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -4,8 +4,9 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @PolyGrowable @PolyReplaceable @PolyShrinkable}. A polymorphic - * qualifier for all three modifiability hierarchies. + * Convenience alias meaning + * {@code @PolyGrowable @PolyReplaceable @PolyShrinkable @PolySeqGrowable}. A polymorphic qualifier + * for all four modifiability hierarchies. * *

Write {@code @PolyModifiable} on methods that preserve or transfer modifiability, such as * {@code List.subList()} and {@code stream()}. diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolySeqGrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolySeqGrowable.java new file mode 100644 index 000000000000..5edd895d7900 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolySeqGrowable.java @@ -0,0 +1,20 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the sequenced-grow hierarchy. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(MaybeSeqGrowable.class) +public @interface PolySeqGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java new file mode 100644 index 000000000000..ce329fe46e61 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling sequenced-grow operations such as {@code addFirst}, {@code addLast}, {@code offerFirst}, + * {@code offerLast}, and {@code push} on this collection will not throw {@link + * UnsupportedOperationException}. + * + *

No guarantees are made about ordinary grow, shrink, or replace operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(MaybeSeqGrowable.class) +public @interface SeqGrowable {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java new file mode 100644 index 000000000000..26c67f1cfeb8 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java @@ -0,0 +1,23 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Calling sequenced-grow operations such as {@code addFirst}, {@code addLast}, {@code offerFirst}, + * {@code offerLast}, and {@code push} on this collection will throw {@link + * UnsupportedOperationException}. + * + *

No guarantees are made about ordinary grow, shrink, or replace operations. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(MaybeSeqGrowable.class) +public @interface SeqUngrowable {} From 4c2825bbabf9311e7042513fc8a7a775f5fc730a Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Jun 2026 15:35:48 -0700 Subject: [PATCH 105/119] fixed typo in treeSet annotation --- src/java.base/share/classes/java/util/TreeSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 5bc8b3b2289b..870f6fcbecbd 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -133,7 +133,7 @@ /** * Constructs a set backed by the specified navigable map. */ - @Modifiable @IteratorPolyMod TreeSet(NavigableMap m) { + @Growable @Shrinkable @Replaceable @SeqUngrowable @IteratorPolyMod TreeSet(NavigableMap m) { this.m = m; } From 6fb270e9605566f80fe55c79f6a0ec869460eae2 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 1 Jun 2026 22:08:14 -0700 Subject: [PATCH 106/119] annotated @SeqGrow in jdk. --- .../classes/java/util/LinkedHashMap.java | 9 ++++--- .../java/util/ReverseOrderSortedMapView.java | 5 ++-- .../share/classes/java/util/SequencedMap.java | 7 +++-- .../share/classes/java/util/SortedMap.java | 9 ++++--- .../share/classes/java/util/TreeMap.java | 27 ++++++++++--------- .../concurrent/ConcurrentSkipListMap.java | 23 ++++++++-------- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 443bcefe7b22..f46bab271545 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -417,7 +418,7 @@ void afterNodeAccess(Node e) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { + public V putFirst(@SeqGrowable LinkedHashMap this, K k, V v) { try { putMode = PUT_FIRST; return this.put(k, v); @@ -436,7 +437,7 @@ public V putFirst(@Growable @Replaceable LinkedHashMap this, K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putLast(@Growable @Replaceable LinkedHashMap this, K k, V v) { + public V putLast(@SeqGrowable LinkedHashMap this, K k, V v) { try { putMode = PUT_LAST; return this.put(k, v); @@ -1388,13 +1389,13 @@ public Entry pollLastEntry(@Shrinkable ReversedLinkedHashMapView this // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putFirst(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { + public V putFirst(@SeqGrowable ReversedLinkedHashMapView this, K k, V v) { return base.putLast(k, v); } // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public V putLast(@Growable @Replaceable ReversedLinkedHashMapView this, K k, V v) { + public V putLast(@SeqGrowable ReversedLinkedHashMapView this, K k, V v) { return base.putFirst(k, v); } } diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index c7cf58a7393f..992a6a614bc0 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.Pure; @@ -189,11 +190,11 @@ public Map.Entry pollLastEntry(@Shrinkable ReverseOrderSortedMapView t return base.pollFirstEntry(); } - public V putFirst(@Growable @Replaceable ReverseOrderSortedMapView this, K k, V v) { + public V putFirst(@SeqGrowable ReverseOrderSortedMapView this, K k, V v) { return base.putLast(k, v); } - public V putLast(@Growable @Replaceable ReverseOrderSortedMapView this, K k, V v) { + public V putLast(@SeqGrowable ReverseOrderSortedMapView this, K k, V v) { return base.putFirst(k, v); } diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index a584cc370b09..031cf21899bc 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -25,10 +25,9 @@ package java.util; -import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; -import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.dataflow.qual.Pure; @@ -255,7 +254,7 @@ default Map.Entry pollLastEntry(@Shrinkable SequencedMap this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { + default V putFirst(@SeqGrowable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -276,7 +275,7 @@ default V putFirst(@Growable @Replaceable SequencedMap this, K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - default V putLast(@Growable @Replaceable SequencedMap this, K k, V v) { + default V putLast(@SeqGrowable SequencedMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 5a7c0460749d..31593c202581 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -27,9 +27,10 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -128,7 +129,7 @@ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public interface SortedMap extends SequencedMap { +public @SeqUngrowable interface SortedMap extends SequencedMap { /** * Returns the comparator used to order the keys in this map, or * {@code null} if this map uses the {@linkplain Comparable @@ -323,7 +324,7 @@ public interface SortedMap extends SequencedMap { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - default V putFirst(K k, V v) { + default V putFirst(@SeqGrowable SortedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -341,7 +342,7 @@ default V putFirst(K k, V v) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - default V putLast(K k, V v) { + default V putLast(@SeqGrowable SortedMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 7a81625ea84a..8b86508d9fe9 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -29,10 +29,11 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -149,7 +150,7 @@ @CFComment({"lock/nullness: This permits null element when using a custom comparator that allows null"}) @AnnotatedFor({"lock", "nullness", "index", "modifiability"}) -public class TreeMap +public @SeqUngrowable class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java.io.Serializable { @@ -186,7 +187,7 @@ public class TreeMap * {@code put(Object key, Object value)} call will throw a * {@code ClassCastException}. */ - public @Modifiable TreeMap() { + public @Growable @Shrinkable @Replaceable @SeqUngrowable TreeMap() { comparator = null; } @@ -204,7 +205,7 @@ public class TreeMap * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ - public @Modifiable TreeMap(@Nullable Comparator comparator) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable TreeMap(@Nullable Comparator comparator) { this.comparator = comparator; } @@ -222,7 +223,7 @@ public class TreeMap * or are not mutually comparable * @throws NullPointerException if the specified map is null */ - public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @PolyNonEmpty TreeMap(@PolyNonEmpty Map m) { comparator = null; putAll(m); } @@ -236,7 +237,7 @@ public class TreeMap * and whose comparator is to be used to sort this map * @throws NullPointerException if the specified map is null */ - public @Modifiable @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable @PolyNonEmpty TreeMap(@PolyNonEmpty SortedMap m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); @@ -357,7 +358,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - public V putFirst(K k, V v) { + public V putFirst(@SeqGrowable TreeMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -372,7 +373,7 @@ public V putFirst(K k, V v) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - public V putLast(K k, V v) { + public V putLast(@SeqGrowable TreeMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -729,7 +730,7 @@ public V computeIfPresent(@Shrinkable @Replaceable TreeMap this, K key, BiF */ @Override @DoesNotUnrefineReceiver("modifiability") - public V compute(@Modifiable TreeMap this, K key, BiFunction remappingFunction) { + public V compute(@Growable @Shrinkable @Replaceable TreeMap this, K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V newValue; Entry t = root; @@ -792,7 +793,7 @@ else if (cmp > 0) */ @Override @DoesNotUnrefineReceiver("modifiability") - public V merge(@Modifiable TreeMap this, K key, V value, BiFunction remappingFunction) { + public V merge(@Growable @Shrinkable @Replaceable TreeMap this, K key, V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); Entry t = root; @@ -997,7 +998,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * @return a shallow copy of this map */ @SideEffectFree - public @Modifiable Object clone(@GuardSatisfied TreeMap this) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable Object clone(@GuardSatisfied TreeMap this) { TreeMap clone; try { clone = (TreeMap) super.clone(); @@ -1995,7 +1996,7 @@ public V putIfAbsent(@Growable NavigableSubMap this, K key, V value) { } @DoesNotUnrefineReceiver("modifiability") - public V merge(@Modifiable NavigableSubMap this, K key, V value, BiFunction remappingFunction) { + public V merge(@Growable @Shrinkable @Replaceable NavigableSubMap this, K key, V value, BiFunction remappingFunction) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.merge(key, value, remappingFunction); @@ -2013,7 +2014,7 @@ public V computeIfAbsent(@Growable NavigableSubMap this, K key, Function this, K key, BiFunction remappingFunction) { + public V compute(@Growable @Shrinkable @Replaceable NavigableSubMap this, K key, BiFunction remappingFunction) { if (!inRange(key)) { // Do not throw if remapping function returns null // to preserve compatibility with default computeIfAbsent implementation diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 424905b57961..bbc27e5cd0b0 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -38,10 +38,11 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; -import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.SeqGrowable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; @@ -134,7 +135,7 @@ * @since 1.6 */ @AnnotatedFor({"nullness", "modifiability"}) -public class ConcurrentSkipListMap extends AbstractMap +public @SeqUngrowable class ConcurrentSkipListMap extends AbstractMap implements ConcurrentNavigableMap, Cloneable, Serializable { /* * This class implements a tree-like two-dimensionally linked skip @@ -1094,7 +1095,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * Constructs a new, empty map, sorted according to the * {@linkplain Comparable natural ordering} of the keys. */ - public @Modifiable ConcurrentSkipListMap() { + public @Growable @Shrinkable @Replaceable @SeqUngrowable ConcurrentSkipListMap() { this.comparator = null; } @@ -1106,7 +1107,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * If {@code null}, the {@linkplain Comparable natural * ordering} of the keys will be used. */ - public @Modifiable ConcurrentSkipListMap(Comparator comparator) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable ConcurrentSkipListMap(Comparator comparator) { this.comparator = comparator; } @@ -1121,7 +1122,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * @throws NullPointerException if the specified map or any of its keys * or values are null */ - public @Modifiable ConcurrentSkipListMap(Map m) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable ConcurrentSkipListMap(Map m) { this.comparator = null; putAll(m); } @@ -1135,7 +1136,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * @throws NullPointerException if the specified sorted map or any of * its keys or values are null */ - public @Modifiable ConcurrentSkipListMap(SortedMap m) { + public @Growable @Shrinkable @Replaceable @SeqUngrowable ConcurrentSkipListMap(SortedMap m) { this.comparator = m.comparator(); buildFromSorted(m); // initializes transients } @@ -1147,7 +1148,7 @@ final AbstractMap.SimpleImmutableEntry findNearEntry(K key, int rel, * @return a shallow copy of this map */ @SideEffectFree - public @Modifiable ConcurrentSkipListMap clone() { + public @Growable @Shrinkable @Replaceable @SeqUngrowable ConcurrentSkipListMap clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListMap clone = @@ -1551,7 +1552,7 @@ else if (doRemove(key, v) != null) * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - public @PolyNull V compute(@Modifiable ConcurrentSkipListMap this, K key, + public @PolyNull V compute(@Growable @Shrinkable @Replaceable ConcurrentSkipListMap this, K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); @@ -1591,7 +1592,7 @@ else if (doRemove(key, v) != null) * @since 1.8 */ @DoesNotUnrefineReceiver("modifiability") - public @PolyNull V merge(@Modifiable ConcurrentSkipListMap this, K key, @NonNull V value, + public @PolyNull V merge(@Growable @Shrinkable @Replaceable ConcurrentSkipListMap this, K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) throw new NullPointerException(); @@ -1943,7 +1944,7 @@ public K lastKey(@NonEmpty ConcurrentSkipListMap this) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - public V putFirst(K k, V v) { + public V putFirst(@SeqGrowable ConcurrentSkipListMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -1958,7 +1959,7 @@ public V putFirst(K k, V v) { // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @ThrowsUOE - public V putLast(K k, V v) { + public V putLast(@SeqGrowable ConcurrentSkipListMap this, K k, V v) { throw new UnsupportedOperationException(); } From 6de9e0b5a8cea19d627554302f9c0cd68fdca4ba Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 3 Jun 2026 12:21:59 -0700 Subject: [PATCH 107/119] annotate NagivableSet as @SeqUngrowable --- src/java.base/share/classes/java/util/NavigableSet.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index e35ceacea9c7..3bb2a7e1cf87 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.PolyGrowShrink; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.PolyModifiable; +import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; @@ -101,7 +102,7 @@ */ @CFComment({"lock/nullness: Subclasses of this interface/class may opt to prohibit null elements"}) @AnnotatedFor({"lock", "nullness"}) -public interface NavigableSet extends SortedSet { +public @SeqUngrowable interface NavigableSet extends SortedSet { /** * Returns the greatest element in this set strictly less than the * given element, or {@code null} if there is no such element. From 403aa9c8aa334fc9367e4b80f95da104c87d16e2 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Wed, 3 Jun 2026 13:17:04 -0700 Subject: [PATCH 108/119] remove throwsUOE and rebuild checker jar. --- checker-qual.jar | Bin 295543 -> 295051 bytes .../classes/java/util/AbstractCollection.java | 1 - .../share/classes/java/util/SortedMap.java | 3 --- .../share/classes/java/util/SortedSet.java | 3 --- .../share/classes/java/util/TreeMap.java | 3 --- .../share/classes/java/util/TreeSet.java | 3 --- .../concurrent/ConcurrentSkipListMap.java | 3 --- .../concurrent/ConcurrentSkipListSet.java | 3 --- .../formatter/qual/ConversionCategory.java | 19 ++++++++++-------- .../checker/formatter/qual/FormatBottom.java | 2 +- .../qual/I18nConversionCategory.java | 6 ++---- .../i18nformatter/qual/I18nFormatBottom.java | 2 +- .../interning/qual/InternedDistinct.java | 2 +- .../modifiability/qual/IteratorPolyMod.java | 2 +- .../modifiability/qual/MaybeSeqGrowable.java | 8 ++++---- .../modifiability/qual/SeqGrowable.java | 4 ++-- .../modifiability/qual/SeqUngrowable.java | 4 ++-- .../checker/modifiability/qual/ThrowsUOE.java | 17 ---------------- .../checker/regex/qual/RegexBottom.java | 2 +- .../sqlquotes/qual/SqlQuotesBottom.java | 2 +- .../returnsreceiver/qual/UnknownThis.java | 2 +- 21 files changed, 28 insertions(+), 63 deletions(-) delete mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java diff --git a/checker-qual.jar b/checker-qual.jar index 0608bc8a10e7c1cced15971f9d33a111408de6c8..f092820db78cf011f728166dc7155ea511a0a7b3 100644 GIT binary patch delta 17828 zcmb_@cRZGF^uK4w-g^_t-g_%6G7~bQ>`i3zkdc&?aa$P~MP*imvPw%v_TD2~Atb)n zb(=ygVVws|vp^Hj&T;;0j_3=-!eWe$3k>+ZnB(v>xS=VMQ zg^x4Oiu|uop}q%ssUoN4pfhP~{+!Am9=ygO@fkq)WZZf6LF?U2L`s#RaH6r7{<=tt z^mL?E3OOE1YceBPuKnwNlstQNX1w@x2EW2pO+TRv)&odCyq7aqGA1}@o!BTx;FZ#r z6&mH(#vdTwi6_&zZh7^zIv+CckOaN?@K&Ld{ca0a(#DrxnyFJC#!M-va3kUL*%i|- zs6QU=>~BtO_U_18+0*ndk#&z}Ue2ap!=J$oh z`b+$GXv!PniHU!D81pt=wJdSg8>zS>9<9&v<@)Aj)8upYWnbZa{%@{BU9x1519gB9 zf3h{r%qqj#tPerl_}H>pSU-ySjDFth%N6Qqs;m*Wg=ULX_^##I+558%!+dP&I=OB> zjSymfRK|(w8;zGTzJ|!XJyl>et-JUD&>BsY=rfSgKLQ!$>wx&tD}tyv39?eWxyUIDb
Kfw4qlm8qNN`% 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

t3@1* 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 diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 0c7375469f9f..bdc7b2dea67c 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -35,7 +35,6 @@ import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 31593c202581..b389fc67377d 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -31,7 +31,6 @@ import org.checkerframework.checker.modifiability.qual.PolyShrinkable; import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.KeyFor; @@ -323,7 +322,6 @@ */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE default V putFirst(@SeqGrowable SortedMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -341,7 +339,6 @@ default V putFirst(@SeqGrowable SortedMap this, K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE default V putLast(@SeqGrowable SortedMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index 5478da47d74b..f217c93635d2 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -30,7 +30,6 @@ import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.checker.nullness.qual.Nullable; @@ -303,7 +302,6 @@ public Comparator getComparator() { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE default void addFirst(@SeqGrowable SortedSet this, E e) { throw new UnsupportedOperationException(); } @@ -322,7 +320,6 @@ default void addFirst(@SeqGrowable SortedSet this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE default void addLast(@SeqGrowable SortedSet this, E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 8b86508d9fe9..e7872f47ad7d 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -35,7 +35,6 @@ import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -357,7 +356,6 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE public V putFirst(@SeqGrowable TreeMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -372,7 +370,6 @@ public V putFirst(@SeqGrowable TreeMap this, K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE public V putLast(@SeqGrowable TreeMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index 870f6fcbecbd..f7bf01598134 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -35,7 +35,6 @@ import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -538,7 +537,6 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE public void addFirst(@SeqGrowable TreeSet this, E e) { throw new UnsupportedOperationException(); } @@ -554,7 +552,6 @@ public void addFirst(@SeqGrowable TreeSet this, E e) { @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE public void addLast(@SeqGrowable TreeSet this, E e) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index bbc27e5cd0b0..ea10c35aae08 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -44,7 +44,6 @@ import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.modifiability.qual.Unmodifiable; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -1943,7 +1942,6 @@ public K lastKey(@NonEmpty ConcurrentSkipListMap this) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE public V putFirst(@SeqGrowable ConcurrentSkipListMap this, K k, V v) { throw new UnsupportedOperationException(); } @@ -1958,7 +1956,6 @@ public V putFirst(@SeqGrowable ConcurrentSkipListMap this, K k, V v) { */ // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - @ThrowsUOE public V putLast(@SeqGrowable ConcurrentSkipListMap this, K k, V v) { throw new UnsupportedOperationException(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 1e39664685f3..58a77ea8ec17 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -44,7 +44,6 @@ import org.checkerframework.checker.modifiability.qual.SeqGrowable; import org.checkerframework.checker.modifiability.qual.SeqUngrowable; import org.checkerframework.checker.modifiability.qual.Shrinkable; -import org.checkerframework.checker.modifiability.qual.ThrowsUOE; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; @@ -464,7 +463,6 @@ public E last(@NonEmpty ConcurrentSkipListSet this) { * @throws UnsupportedOperationException always * @since 21 */ - @ThrowsUOE @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") @@ -480,7 +478,6 @@ public void addFirst(@SeqGrowable ConcurrentSkipListSet this, E e) { * @throws UnsupportedOperationException always * @since 21 */ - @ThrowsUOE @EnsuresNonEmpty("this") // @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") diff --git a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java index 2a3dbd7c899a..0dabb92c2d23 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java +++ b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java @@ -187,8 +187,9 @@ public enum ConversionCategory { * The conversion categories that have a corresponding conversion character. This lacks UNUSED, * TIME_AND_INT, etc. */ - private static final ConversionCategory[] conversionCategoriesWithChar = - new ConversionCategory[] {GENERAL, CHAR, INT, FLOAT, TIME}; + private static final ConversionCategory[] conversionCategoriesWithChar = { + GENERAL, CHAR, INT, FLOAT, TIME + }; /** * Converts a conversion character to a category. For example: @@ -219,8 +220,9 @@ public static boolean isSubsetOf(ConversionCategory a, ConversionCategory b) { } /** Conversion categories that need to be considered by {@link #intersect}. */ - private static final ConversionCategory[] conversionCategoriesForIntersect = - new ConversionCategory[] {CHAR, INT, FLOAT, TIME, CHAR_AND_INT, INT_AND_TIME, NULL}; + private static final ConversionCategory[] conversionCategoriesForIntersect = { + CHAR, INT, FLOAT, TIME, CHAR_AND_INT, INT_AND_TIME, NULL + }; /** * Returns the intersection of two categories. This is seldom needed. @@ -270,8 +272,9 @@ public static ConversionCategory intersect(ConversionCategory a, ConversionCateg } /** Conversion categories that need to be considered by {@link #union}. */ - private static final ConversionCategory[] conversionCategoriesForUnion = - new ConversionCategory[] {NULL, CHAR_AND_INT, INT_AND_TIME, CHAR, INT, FLOAT, TIME}; + private static final ConversionCategory[] conversionCategoriesForUnion = { + NULL, CHAR_AND_INT, INT_AND_TIME, CHAR, INT, FLOAT, TIME + }; /** * Returns the union of two categories. This is seldom needed. @@ -346,7 +349,7 @@ public boolean isAssignableFrom(Class argType) { @Pure @Override public String toString() { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(32); sb.append(name()); sb.append(" conversion category"); @@ -358,7 +361,7 @@ public String toString() { for (Class cls : types) { sj.add(cls.getSimpleName()); } - sb.append(" "); + sb.append(' '); sb.append(sj); return sb.toString(); diff --git a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/FormatBottom.java b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/FormatBottom.java index 9ce0ec040f52..87263ecb9b04 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/FormatBottom.java +++ b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/FormatBottom.java @@ -21,5 +21,5 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @SubtypeOf({Format.class, InvalidFormat.class}) -@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +@DefaultFor({TypeUseLocation.LOWER_BOUND}) public @interface FormatBottom {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java b/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java index 0438bbfdf3cc..02da76a4c901 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java +++ b/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java @@ -64,8 +64,7 @@ public enum I18nConversionCategory { } /** Used by {@link #stringToI18nConversionCategory}. */ - private static final I18nConversionCategory[] namedCategories = - new I18nConversionCategory[] {DATE, NUMBER}; + private static final I18nConversionCategory[] namedCategories = {DATE, NUMBER}; /** * Creates a conversion cagetogry from a string name. @@ -104,8 +103,7 @@ public static boolean isSubsetOf(I18nConversionCategory a, I18nConversionCategor } /** Conversion categories that need to be considered by {@link #intersect}. */ - private static final I18nConversionCategory[] conversionCategoriesForIntersect = - new I18nConversionCategory[] {DATE, NUMBER}; + private static final I18nConversionCategory[] conversionCategoriesForIntersect = {DATE, NUMBER}; /** * Returns the intersection of the two given I18nConversionCategories. diff --git a/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java b/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java index 44637a30b819..941f4e61d7cd 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java +++ b/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java @@ -22,5 +22,5 @@ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @SubtypeOf({I18nFormat.class, I18nInvalidFormat.class, I18nFormatFor.class}) -@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +@DefaultFor({TypeUseLocation.LOWER_BOUND}) public @interface I18nFormatBottom {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/interning/qual/InternedDistinct.java b/src/java.base/share/classes/org/checkerframework/checker/interning/qual/InternedDistinct.java index c1e7fb54a8cb..80b80e37cfaf 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/interning/qual/InternedDistinct.java +++ b/src/java.base/share/classes/org/checkerframework/checker/interning/qual/InternedDistinct.java @@ -25,5 +25,5 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf(Interned.class) -@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +@DefaultFor({TypeUseLocation.LOWER_BOUND}) public @interface InternedDistinct {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java index ec4c8d2b8de1..eab5c7afc93e 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java @@ -9,7 +9,7 @@ /** * If a collection's type is {@code @IteratorPolyMod}, then its {@code iterator()} and {@code - * listIterator()} methods preserves the ability to call modification methods in its iterator. + * listIterator()} methods preserve the ability to call modification methods in its iterator. * *

For example, if collection {@code c} has type {@code @Shrinkable}, then {@code c.iterator()} * also has type {@code @Shrinkable}. If list {@code l} has type {@code @Replaceable}, then {@code diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java index edc800772346..27e7feb3dc8c 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeSeqGrowable.java @@ -9,10 +9,10 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * The top qualifier in the sequenced-grow hierarchy. The collection may or may not support - * positional grow operations such as {@code addFirst} and {@code addLast}. The checker - * conservatively issues an error wherever a sequenced-grow operation is called on a - * {@code @MaybeSeqGrowable} expression. + * The top qualifier in the sequenced-grow hierarchy. The collection or map may or may not support + * positional operations such as {@code addFirst}, {@code addLast}, {@code putFirst}, and {@code + * putLast}. The checker conservatively issues an error wherever a sequenced-grow operation is + * called on a {@code @MaybeSeqGrowable} expression. * *

This is the default qualifier for unannotated types in the sequenced-grow hierarchy. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java index ce329fe46e61..3714fe5909d9 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqGrowable.java @@ -9,8 +9,8 @@ /** * Calling sequenced-grow operations such as {@code addFirst}, {@code addLast}, {@code offerFirst}, - * {@code offerLast}, and {@code push} on this collection will not throw {@link - * UnsupportedOperationException}. + * {@code offerLast}, {@code push}, {@code putFirst}, and {@code putLast} on this collection or map + * will not throw {@link UnsupportedOperationException}. * *

No guarantees are made about ordinary grow, shrink, or replace operations. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java index 26c67f1cfeb8..ff6c4008ed1f 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/SeqUngrowable.java @@ -9,8 +9,8 @@ /** * Calling sequenced-grow operations such as {@code addFirst}, {@code addLast}, {@code offerFirst}, - * {@code offerLast}, and {@code push} on this collection will throw {@link - * UnsupportedOperationException}. + * {@code offerLast}, {@code push}, {@code putFirst}, and {@code putLast} on this collection or map + * will throw {@link UnsupportedOperationException}. * *

No guarantees are made about ordinary grow, shrink, or replace operations. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java deleted file mode 100644 index 1275077f2023..000000000000 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/ThrowsUOE.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.checkerframework.checker.modifiability.qual; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The annotated method always throws {@link UnsupportedOperationException} when called. - * - * @checker_framework.manual #modifiability-checker Modifiability Checker - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) -public @interface ThrowsUOE {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java b/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java index 2ffcb62ad718..b948170765bd 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java +++ b/src/java.base/share/classes/org/checkerframework/checker/regex/qual/RegexBottom.java @@ -23,5 +23,5 @@ @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @InvisibleQualifier @SubtypeOf({Regex.class, PartialRegex.class}) -@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +@DefaultFor({TypeUseLocation.LOWER_BOUND}) public @interface RegexBottom {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java index 41acaca1641d..542f2a288119 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java +++ b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java @@ -23,5 +23,5 @@ @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @InvisibleQualifier @SubtypeOf({SqlEvenQuotes.class, SqlOddQuotes.class}) -@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +@DefaultFor({TypeUseLocation.LOWER_BOUND}) public @interface SqlQuotesBottom {} diff --git a/src/java.base/share/classes/org/checkerframework/common/returnsreceiver/qual/UnknownThis.java b/src/java.base/share/classes/org/checkerframework/common/returnsreceiver/qual/UnknownThis.java index 7ada21419f1e..70b38d5de7c1 100644 --- a/src/java.base/share/classes/org/checkerframework/common/returnsreceiver/qual/UnknownThis.java +++ b/src/java.base/share/classes/org/checkerframework/common/returnsreceiver/qual/UnknownThis.java @@ -23,6 +23,6 @@ @SubtypeOf({}) @DefaultQualifierInHierarchy @QualifierForLiterals(LiteralKind.NULL) -@DefaultFor(value = TypeUseLocation.LOWER_BOUND) +@DefaultFor(TypeUseLocation.LOWER_BOUND) @InvisibleQualifier public @interface UnknownThis {} From 39c4232163878058bf17ac63918783a5c59e0f60 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Fri, 5 Jun 2026 17:51:20 -0700 Subject: [PATCH 109/119] annotating @PolyIteratorPolyMod Co-authored-by: Copilot --- .../share/classes/java/util/Collections.java | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 829c25147996..738be6638914 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; +import org.checkerframework.checker.modifiability.qual.PolyIteratorPolyMod; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.modifiability.qual.PolyModifiable; @@ -64,6 +65,38 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Array; +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Collections.AsLIFOQueue; +import java.util.Collections.CheckedCollection; +import java.util.Collections.CheckedList; +import java.util.Collections.CheckedMap.CheckedEntrySet; +import java.util.Collections.CheckedNavigableMap; +import java.util.Collections.CheckedNavigableSet; +import java.util.Collections.CheckedQueue; +import java.util.Collections.CheckedRandomAccessList; +import java.util.Collections.CheckedSet; +import java.util.Collections.CheckedSortedMap; +import java.util.Collections.CheckedSortedSet; +import java.util.Collections.SynchronizedCollection; +import java.util.Collections.SynchronizedList; +import java.util.Collections.SynchronizedNavigableMap; +import java.util.Collections.SynchronizedNavigableSet; +import java.util.Collections.SynchronizedRandomAccessList; +import java.util.Collections.SynchronizedSet; +import java.util.Collections.SynchronizedSortedMap; +import java.util.Collections.SynchronizedSortedSet; +import java.util.Collections.UnmodifiableCollection; +import java.util.Collections.UnmodifiableList; +import java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet; +import java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet.UnmodifiableEntrySetSpliterator; +import java.util.Collections.UnmodifiableNavigableMap; +import java.util.Collections.UnmodifiableNavigableSet; +import java.util.Collections.UnmodifiableRandomAccessList; +import java.util.Collections.UnmodifiableSequencedCollection; +import java.util.Collections.UnmodifiableSequencedSet; +import java.util.Collections.UnmodifiableSet; +import java.util.Collections.UnmodifiableSortedMap; +import java.util.Collections.UnmodifiableSortedSet; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -2526,11 +2559,11 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) * @param c the collection to be "wrapped" in a synchronized collection. * @return a synchronized view of the specified collection. */ - public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection c) { + public static @PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty Collection c) { return new SynchronizedCollection<>(c); } - static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection c, Object mutex) { + static @PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty Collection synchronizedCollection(@PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty Collection c, Object mutex) { return new SynchronizedCollection<>(c, mutex); } @@ -2683,11 +2716,11 @@ private void writeObject(ObjectOutputStream s) throws IOException { * @param s the set to be "wrapped" in a synchronized set. * @return a synchronized view of the specified set. */ - public static @PolyModifiable Set synchronizedSet(@PolyModifiable Set s) { + public static @PolyModifiable @PolyIteratorPolyMod Set synchronizedSet(@PolyModifiable @PolyIteratorPolyMod Set s) { return new SynchronizedSet<>(s); } - static @PolyModifiable Set synchronizedSet(@PolyModifiable Set s, Object mutex) { + static @PolyModifiable @PolyIteratorPolyMod Set synchronizedSet(@PolyModifiable @PolyIteratorPolyMod Set s, Object mutex) { return new SynchronizedSet<>(s, mutex); } @@ -2963,13 +2996,13 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @param list the list to be "wrapped" in a synchronized list. * @return a synchronized view of the specified list. */ - public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List list) { + public static @PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty List list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list) : new SynchronizedList<>(list)); } - static @PolyGrowShrink @PolyModifiable @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List list, Object mutex) { + static @PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty List synchronizedList(@PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty List list, Object mutex) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list, mutex) : new SynchronizedList<>(list, mutex)); @@ -3688,7 +3721,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { * @return a dynamically typesafe view of the specified collection * @since 1.5 */ - public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection checkedCollection(@PolyGrowShrink @PolyModifiable @PolyNonEmpty Collection c, + public static @PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty Collection checkedCollection(@PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty Collection c, Class type) { return new CheckedCollection<>(c, type); } @@ -3942,7 +3975,7 @@ static class CheckedQueue * @return a dynamically typesafe view of the specified set * @since 1.5 */ - public static @PolyModifiable Set checkedSet(@PolyModifiable Set s, Class type) { + public static @PolyModifiable @PolyIteratorPolyMod Set checkedSet(@PolyModifiable @PolyIteratorPolyMod Set s, Class type) { return new CheckedSet<>(s, type); } @@ -4146,7 +4179,7 @@ public NavigableSet tailSet(E fromElement, boolean inclusive) { * @return a dynamically typesafe view of the specified list * @since 1.5 */ - public static @PolyGrowShrink @PolyModifiable @PolyNonEmpty List checkedList(@PolyGrowShrink @PolyModifiable @PolyNonEmpty List list, Class type) { + public static @PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty List checkedList(@PolyGrowShrink @PolyModifiable @PolyIteratorPolyMod @PolyNonEmpty List list, Class type) { return (list instanceof RandomAccess ? new CheckedRandomAccessList<>(list, type) : new CheckedList<>(list, type)); From aa4a47876790cb4365c01d98fd6992a43b7156a0 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 7 Jun 2026 16:05:38 -0700 Subject: [PATCH 110/119] annotate ProcessBuilder. --- src/java.base/share/classes/java/lang/ProcessBuilder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/ProcessBuilder.java b/src/java.base/share/classes/java/lang/ProcessBuilder.java index 5c9453402f29..c7cf224de855 100644 --- a/src/java.base/share/classes/java/lang/ProcessBuilder.java +++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java @@ -26,6 +26,7 @@ package java.lang; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.mustcall.qual.MustCall; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.tainting.qual.Untainted; @@ -200,7 +201,7 @@ public final class ProcessBuilder // Lazily and racy initialize when needed, racy is ok, any logger is ok private static System.Logger LOGGER; - @Modifiable private List command; + @Modifiable @IteratorPolyMod private List command; private File directory; private Map environment; private boolean redirectErrorStream; @@ -284,7 +285,7 @@ public ProcessBuilder command(@Untainted String... command) { * * @return this process builder's program and its arguments */ - public @Modifiable List<@Untainted String> command() { + public @Modifiable @IteratorPolyMod List<@Untainted String> command() { return command; } From 43123f7290e651c8c48e2e2418076180d940b70a Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 8 Jun 2026 16:25:44 -0700 Subject: [PATCH 111/119] annotate @IteratorPolyMod on arrays.asList. Co-authored-by: Copilot --- src/java.base/share/classes/java/util/Arrays.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 6d1a930f8322..dd7bebf99d88 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.interning.qual.PolyInterned; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.modifiability.qual.Replaceable; +import org.checkerframework.checker.modifiability.qual.IteratorPolyMod; import org.checkerframework.checker.mustcall.qual.MustCallUnknown; import org.checkerframework.checker.mustcall.qual.PolyMustCall; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -4294,7 +4295,7 @@ private static boolean[] copyOfRangeBoolean(boolean[] original, int from, int to @SafeVarargs @SideEffectFree @SuppressWarnings("varargs") - public static @Replaceable @PolyNonEmpty List asList(T @PolyNonEmpty... a) { + public static @Replaceable @IteratorPolyMod @PolyNonEmpty List asList(T @PolyNonEmpty... a) { return new ArrayList<>(a); } From b2876cb498e781cbdd7adfa118ac5a8258209af3 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Mon, 8 Jun 2026 17:56:13 -0700 Subject: [PATCH 112/119] annotated getOrDefault. Co-authored-by: Copilot --- src/java.base/share/classes/java/util/HashMap.java | 4 +++- src/java.base/share/classes/java/util/Hashtable.java | 4 +++- src/java.base/share/classes/java/util/LinkedHashMap.java | 8 ++++++-- src/java.base/share/classes/java/util/Map.java | 2 +- src/java.base/share/classes/java/util/Properties.java | 3 ++- .../classes/java/util/concurrent/ConcurrentHashMap.java | 4 +++- .../share/classes/java/util/concurrent/ConcurrentMap.java | 5 ++++- .../java/util/concurrent/ConcurrentSkipListMap.java | 4 +++- 8 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index e2e56d733575..57104074c14e 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -1229,7 +1229,9 @@ public final void forEach(Consumer> action) { @Override @Pure - public V getOrDefault(HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key, V defaultValue) { + public @PolyModifiable V getOrDefault(HashMap this, + @GuardSatisfied @Nullable @UnknownSignedness Object key, + @PolyModifiable V defaultValue) { Node e; return (e = getNode(key)) == null ? defaultValue : e.value; } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index cb7eaf080620..f6ba93a28f90 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -957,7 +957,9 @@ public synchronized int hashCode(@GuardSatisfied Hashtable this) { @Override @Pure - public synchronized V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultValue) { + public synchronized @PolyModifiable V getOrDefault(Hashtable this, + @GuardSatisfied @UnknownSignedness Object key, + @PolyModifiable V defaultValue) { V result = get(key); return (null == result) ? defaultValue : result; } diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index f46bab271545..f73700ea8284 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -579,7 +579,9 @@ public boolean containsValue(@GuardSatisfied LinkedHashMap this, @GuardSat */ @CFComment("`getOrDefault()` is not strictly pure: if `accessOrder==true`, it changes the access order") @Pure - public V getOrDefault(@Nullable Object key, V defaultValue) { + public @PolyModifiable V getOrDefault(LinkedHashMap this, + @Nullable Object key, + @PolyModifiable V defaultValue) { Node e; if ((e = getNode(key)) == null) return defaultValue; @@ -1289,7 +1291,9 @@ public void clear(@Shrinkable ReversedLinkedHashMapView this) { @CFComment("`getOrDefault()` is not strictly pure: if `accessOrder==true`, it changes the access order") @Pure - public V getOrDefault(Object key, V defaultValue) { + public @PolyModifiable V getOrDefault(ReversedLinkedHashMapView this, + Object key, + @PolyModifiable V defaultValue) { return base.getOrDefault(key, defaultValue); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 4ea0da0de19a..897d3dc33790 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -755,7 +755,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @UnknownSignedness Object key, @PolyModifiable V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 0d4b048197c7..742b87432a69 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -1527,7 +1527,8 @@ public synchronized int hashCode() { @Override @Pure - public Object getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, Object defaultValue) { + public @PolyModifiable Object getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, + @PolyModifiable Object defaultValue) { return map.getOrDefault(key, defaultValue); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 5e565d20aa2e..a5d1fcb14769 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -1658,7 +1658,9 @@ public boolean replace(@Replaceable ConcurrentHashMap this, K key, V oldVal * @throws NullPointerException if the specified key is null */ @Pure - public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultValue) { + public @PolyModifiable V getOrDefault(ConcurrentHashMap this, + @GuardSatisfied @UnknownSignedness Object key, + @PolyModifiable V defaultValue) { V v; return (v = get(key)) == null ? defaultValue : v; } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 25da842e2671..77decb561b4b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.modifiability.qual.Growable; import org.checkerframework.checker.modifiability.qual.MaybeModifiable; import org.checkerframework.checker.modifiability.qual.Modifiable; +import org.checkerframework.checker.modifiability.qual.PolyModifiable; import org.checkerframework.checker.modifiability.qual.Replaceable; import org.checkerframework.checker.modifiability.qual.Shrinkable; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; @@ -99,7 +100,9 @@ public interface ConcurrentMap this,Object key, V defaultValue) { + default @PolyModifiable V getOrDefault(ConcurrentMap this, + Object key, + @PolyModifiable V defaultValue) { V v; return ((v = get(key)) != null) ? v : defaultValue; } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index ea10c35aae08..e470ac5b7a0b 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -1352,7 +1352,9 @@ public V get(Object key) { * @since 1.8 */ @Pure - public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultValue) { + public @PolyModifiable V getOrDefault(ConcurrentSkipListMap this, + @GuardSatisfied @UnknownSignedness Object key, + @PolyModifiable V defaultValue) { V v; return (v = doGet(key)) == null ? defaultValue : v; } From 600a1ebad07b3575d532d5241be1c1abb909f548 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Fri, 12 Jun 2026 12:05:30 -0700 Subject: [PATCH 113/119] Modifiability of `newLinkedHashMap()` --- src/java.base/share/classes/java/util/LinkedHashMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index f73700ea8284..0ca72c7140fc 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -1178,7 +1178,7 @@ public final void remove() { * @throws IllegalArgumentException if numMappings is negative * @since 19 */ - public static LinkedHashMap newLinkedHashMap(int numMappings) { + public static @Modifiable LinkedHashMap newLinkedHashMap(int numMappings) { if (numMappings < 0) { throw new IllegalArgumentException("Negative number of mappings: " + numMappings); } From 77afd0a62646337761a68becf46847f21d10acbb Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Fri, 12 Jun 2026 12:29:29 -0700 Subject: [PATCH 114/119] Remove `@PolyModifiable` from `Map#getOrDefault` --- src/java.base/share/classes/java/util/Map.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 897d3dc33790..2fc8de94521a 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -755,7 +755,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @UnknownSignedness Object key, @PolyModifiable V defaultValue) { + default V getOrDefault(Map this, @GuardSatisfied @UnknownSignedness Object key, V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v From b5187e8899494e51707be109b9661da0840da044 Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 14 Jun 2026 19:04:53 -0700 Subject: [PATCH 115/119] Revert "Remove `@PolyModifiable` from `Map#getOrDefault`" This reverts commit 77afd0a62646337761a68becf46847f21d10acbb. --- src/java.base/share/classes/java/util/Map.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 2fc8de94521a..897d3dc33790 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -755,7 +755,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @UnknownSignedness Object key, V defaultValue) { + default @PolyModifiable V getOrDefault(Map this, @GuardSatisfied @UnknownSignedness Object key, @PolyModifiable V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v From f63526e19191e0c2c9ffb77ed80fb3ce3c4557ba Mon Sep 17 00:00:00 2001 From: YukiYang31 Date: Sun, 14 Jun 2026 20:05:49 -0700 Subject: [PATCH 116/119] update checker jar. --- checker-qual.jar | Bin 295051 -> 295851 bytes .../formatter/qual/ConversionCategory.java | 3 ++- .../qual/I18nConversionCategory.java | 3 ++- .../modifiability/qual/IteratorPolyMod.java | 7 +++-- .../qual/MaybeIteratorPolyMod.java | 2 +- .../modifiability/qual/MaybeModifiable.java | 10 +++++--- .../qual/PolyIteratorPolyMod.java | 24 ++++++++++++++++++ .../modifiability/qual/PolyModifiable.java | 6 ++--- .../qual/PreservesModifiability.java | 12 +++++---- .../modifiability/qual/Unmodifiable.java | 7 ++--- 10 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyIteratorPolyMod.java diff --git a/checker-qual.jar b/checker-qual.jar index f092820db78cf011f728166dc7155ea511a0a7b3..f70c539535b30d13bf214f8ed6871be719311111 100644 GIT binary patch delta 16216 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 Aj{pDw diff --git a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java index 0dabb92c2d23..ebbb00162814 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java +++ b/src/java.base/share/classes/org/checkerframework/checker/formatter/qual/ConversionCategory.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Set; import java.util.StringJoiner; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; @@ -211,7 +212,7 @@ public static ConversionCategory fromConversionChar(char c) { throw new IllegalArgumentException("Bad conversion character " + c); } - private static Set arrayToSet(E[] a) { + private static @Modifiable Set arrayToSet(E[] a) { return new HashSet<>(Arrays.asList(a)); } diff --git a/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java b/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java index 02da76a4c901..8a497c8f0eee 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java +++ b/src/java.base/share/classes/org/checkerframework/checker/i18nformatter/qual/I18nConversionCategory.java @@ -5,6 +5,7 @@ import java.util.HashSet; import java.util.Set; import java.util.StringJoiner; +import org.checkerframework.checker.modifiability.qual.Modifiable; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.AnnotatedFor; @@ -89,7 +90,7 @@ public static I18nConversionCategory stringToI18nConversionCategory(String strin throw new IllegalArgumentException("Invalid format type " + string); } - private static Set arrayToSet(E[] a) { + private static @Modifiable Set arrayToSet(E[] a) { return new HashSet<>(Arrays.asList(a)); } diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java index eab5c7afc93e..0fd6d04fcfd4 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/IteratorPolyMod.java @@ -13,8 +13,11 @@ * *

For example, if collection {@code c} has type {@code @Shrinkable}, then {@code c.iterator()} * also has type {@code @Shrinkable}. If list {@code l} has type {@code @Replaceable}, then {@code - * l.listIterator()} also has type {@code @Replaceable}. For any collection whose type is - * {@code @MaybeIteratorPolyMod}, its iterator is always {@code @MaybeShrinkable}. + * l.listIterator()} also has type {@code @Replaceable}. + * + *

If the collection itself is {@code @Unmodifiable}, then its iterator is {@code @Unshrinkable}. + * For any collection whose type is {@code @MaybeIteratorPolyMod}, its iterator is + * {@code @MaybeShrinkable}. * *

This annotation is used in GrowChecker, ShrinkChecker, and ReplaceChecker. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java index f113fdc671f6..d7a6ea8b5a49 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeIteratorPolyMod.java @@ -9,7 +9,7 @@ import org.checkerframework.framework.qual.SubtypeOf; /** - * For the annotated collection, the return type of {@code iterator()} is {@code @Unshrinkable}. + * For the annotated collection, the return type of {@code iterator()} is {@code @MaybeShrinkable}. * *

This is the default qualifier for unannotated types. * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java index c4b7e274efda..eafb5cce1344 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/MaybeModifiable.java @@ -7,12 +7,14 @@ import java.lang.annotation.Target; /** - * Convenience alias meaning {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable}. Represents - * an unknown or arbitrary modifiability capability; the checker cannot determine whether the - * collection is growable, shrinkable, or replaceable. + * Convenience alias meaning + * {@code @MaybeGrowable @MaybeSeqGrowable @MaybeShrinkable @MaybeReplaceable}. Represents an + * unknown or arbitrary modifiability capability; the checker cannot determine whether the + * collection is growable, sequenced-growable, shrinkable, or replaceable. * *

This annotation is not part of the type hierarchy; the Modifiability Checker expands it to - * {@code @MaybeGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated type. + * {@code @MaybeGrowable @MaybeSeqGrowable @MaybeShrinkable @MaybeReplaceable} on each annotated + * type. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyIteratorPolyMod.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyIteratorPolyMod.java new file mode 100644 index 000000000000..75c43c0090cb --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyIteratorPolyMod.java @@ -0,0 +1,24 @@ +package org.checkerframework.checker.modifiability.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Iterator hierarchy. + * + *

When used on a method, whether the return type has {@code @IteratorPolyMod} matches whether + * the argument or receiver annotated with {@code @PolyIteratorPolyMod} has + * {@code @IteratorPolyMod}. + * + * @checker_framework.manual #modifiability-checker Modifiability Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(MaybeIteratorPolyMod.class) +public @interface PolyIteratorPolyMod {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java index 83724f7d4be5..9467ac599891 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PolyModifiable.java @@ -5,11 +5,11 @@ /** * Convenience alias meaning - * {@code @PolyGrowable @PolyReplaceable @PolyShrinkable @PolySeqGrowable}. A polymorphic qualifier - * for all four modifiability hierarchies. + * {@code @PolyGrowable @PolyReplaceable @PolyShrinkable @PolySeqGrowable @PolyIteratorPolyMod}. A + * polymorphic qualifier for all five modifiability hierarchies. * *

Write {@code @PolyModifiable} on methods that preserve or transfer modifiability, such as - * {@code List.subList()} and {@code stream()}. + * {@code List.subList()}. * *

For example: * diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java index 5bbcc4f6e677..c5f414ad7693 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/PreservesModifiability.java @@ -10,12 +10,14 @@ * The annotated method preserves modifiability capabilities from its first argument to its return * value. * - *

For example, if the first argument is {@code @Modifiable} or {@code @IteratorPolyMod}, then - * the return type is also {@code @Modifiable} or {@code @IteratorPolyMod}. If the first argument is - * anything other than {@code @Modifiable} or {@code @IteratorPolyMod}, then the return type is the - * top {@code @MaybeModifiable}. + *

For example, if the first argument has a positive modifiability capability, such as + * {@code @Growable}, {@code @SeqGrowable}, {@code @Shrinkable}, or {@code @Replaceable}, then the + * return type has that same capability. If the first argument is {@code @IteratorPolyMod}, then the + * return type is also {@code @IteratorPolyMod}. If the first argument has any other qualifier in a + * capability hierarchy, then the return type is the top qualifier in that hierarchy. * - *

If the annotated method has no parameters, then this annotation has no effect on the method. + *

If the annotated method has no parameters or returns {@code void}, then this annotation has no + * effect on the method. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ diff --git a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java index 2e233b798c11..9c4e5fb1dba6 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java +++ b/src/java.base/share/classes/org/checkerframework/checker/modifiability/qual/Unmodifiable.java @@ -7,13 +7,14 @@ import java.lang.annotation.Target; /** - * Convenience alias usually meaning {@code @Ungrowable @Unshrinkable @Unreplaceable}. Calling a - * mutating operation (growing, shrinking, or replacing) may throw {@link + * Convenience alias usually meaning + * {@code @Ungrowable @SeqUngrowable @Unshrinkable @Unreplaceable}. Calling a mutating operation + * (growing, sequenced-growing, shrinking, or replacing) will throw {@link * UnsupportedOperationException}. * *

As an exception, {@code @Unmodifiable} means {@code @Maybe*} if the type does not support a * given category of operation; for example, {@code @Unmodifiable Iterator} means - * {@code @MaybeGrowable @Unshrinkable @MaybeReplaceable Iterator}. + * {@code @MaybeGrowable @MaybeSeqGrowable @Unshrinkable @MaybeReplaceable Iterator}. * * @checker_framework.manual #modifiability-checker Modifiability Checker */ From 89a9748fe44daa2115c22c826e999e69f9b8f41d Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 16 Sep 2026 14:16:35 -0700 Subject: [PATCH 117/119] Fix incorrect purity and qualifier annotations * `SimpleDeque`: add the missing import for `@SideEffectFree`, without which the jtreg support file does not compile. * `Arrays.fill(long[], long)`: `@SideEffectsOnly("#1")` rather than `@Pure`; the body writes `a[i] = val`, and the 15 sibling overloads already use `@SideEffectsOnly("#1")`. * `Collection`, `List`, `Set`, and `Collections.UnmodifiableEntrySet`: remove `@SideEffectFree` from `toArray(T[] a)`, which writes into the caller's array. Commit aa687169ec5 did this for the other implementations but missed these. * `LinkedHashMap.keySet`: restore `@KeyFor({"this"})`, dropped by accident; `HashMap.keySet`, which it overrides, declares it. * `HashMap.entrySet`: the receiver is `@PolyModifiable`, matching `Map`, `AbstractMap`, and `LinkedHashMap`. `@PolyModifiable` in the return type had nothing to resolve against. Co-Authored-By: Claude Opus 5 --- src/java.base/share/classes/java/util/Arrays.java | 2 +- src/java.base/share/classes/java/util/Collection.java | 1 - src/java.base/share/classes/java/util/Collections.java | 1 - src/java.base/share/classes/java/util/HashMap.java | 2 +- src/java.base/share/classes/java/util/LinkedHashMap.java | 2 +- src/java.base/share/classes/java/util/List.java | 1 - src/java.base/share/classes/java/util/Set.java | 1 - test/jdk/java/util/SequencedCollection/SimpleDeque.java | 1 + 8 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 1cbc081c0f81..081873c8ae7c 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -3253,7 +3253,7 @@ public static boolean equals(T[] a, int aFromIndex, int aToIndex, * @param a the array to be filled * @param val the value to be stored in all elements of the array */ - @Pure + @SideEffectsOnly("#1") public static void fill(@PolySigned long[] a, @PolySigned long val) { for (int i = 0, len = a.length; i < len; i++) a[i] = val; diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index bc792a9ac114..52ea21d3941c 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -419,7 +419,6 @@ public interface Collection extends Iterable { * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T[] toArray(@MaybeModifiable Collection this, @PolyNull T[] a); /** diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 585312d4f607..664f39a91d0c 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -2139,7 +2139,6 @@ public Object[] toArray() { } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { // We don't pass a to c.toArray, to avoid window of // vulnerability wherein an unscrupulous multithreaded client diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 97f19a971fe8..b0204a725e07 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -1170,7 +1170,7 @@ public final void forEach(Consumer action) { * @return a set view of the mappings contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyShrinkable @GuardSatisfied HashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set> entrySet(@PolyModifiable @GuardSatisfied HashMap this) { Set> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 40c6aa04af4a..79375231c010 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -665,7 +665,7 @@ protected boolean removeEldestEntry(@GuardSatisfied LinkedHashMap this, Ma * @return a set view of the keys contained in this map */ @SideEffectFree - public @IteratorPolyMod @PolyShrinkable @Ungrowable Set keySet(@PolyShrinkable LinkedHashMap this) { + public @IteratorPolyMod @PolyShrinkable @Ungrowable Set<@KeyFor({"this"}) K> keySet(@PolyShrinkable LinkedHashMap this) { return sequencedKeySet(); } diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 2664f0c9e276..4f0903691ef3 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -279,7 +279,6 @@ public interface List extends SequencedCollection { * this list * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T[] toArray(@MaybeModifiable List this, @PolyNull T[] a); diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 05784f4fb34f..9400e3d6f09f 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -250,7 +250,6 @@ public interface Set extends Collection { * set * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T [] toArray(@MaybeModifiable Set this, @PolyNull T[] a); diff --git a/test/jdk/java/util/SequencedCollection/SimpleDeque.java b/test/jdk/java/util/SequencedCollection/SimpleDeque.java index 3524ba2c075f..4d2e3fa6dc91 100644 --- a/test/jdk/java/util/SequencedCollection/SimpleDeque.java +++ b/test/jdk/java/util/SequencedCollection/SimpleDeque.java @@ -22,6 +22,7 @@ */ import java.util.*; +import org.checkerframework.dataflow.qual.SideEffectFree; /** * A complete Deque implementation that inherits the reversed() method From a20b6fa54764e1266097c3ee07744cb1c288dddd Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Sun, 20 Sep 2026 17:54:48 -0700 Subject: [PATCH 118/119] Fix merge problems --- src/java.base/share/classes/java/util/Collections.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 5b5f857c8297..f58f819e4f39 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -69,7 +69,6 @@ import java.util.Collections.AsLIFOQueue; import java.util.Collections.CheckedCollection; import java.util.Collections.CheckedList; -import java.util.Collections.CheckedMap.CheckedEntrySet; import java.util.Collections.CheckedNavigableMap; import java.util.Collections.CheckedNavigableSet; import java.util.Collections.CheckedQueue; @@ -87,8 +86,6 @@ import java.util.Collections.SynchronizedSortedSet; import java.util.Collections.UnmodifiableCollection; import java.util.Collections.UnmodifiableList; -import java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet; -import java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet.UnmodifiableEntrySetSpliterator; import java.util.Collections.UnmodifiableNavigableMap; import java.util.Collections.UnmodifiableNavigableSet; import java.util.Collections.UnmodifiableRandomAccessList; @@ -4048,7 +4045,6 @@ static class CheckedSortedSet extends CheckedSet ss = s; } - @Pure @Pure public @Nullable Comparator comparator() { return ss.comparator(); } public E first() { return ss.first(); } From e8c2526a7652d4af1ca5420ac35457f77198dcc4 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Mon, 21 Sep 2026 08:47:24 -0700 Subject: [PATCH 119/119] Address code review findings * Restore `@PolyNonEmpty` on `ArrayList.iterator()` and `ArrayList.listIterator()`. * Remove unsound `@PolyNonEmpty` from `AbstractList.listIterator(int)`, which returns an empty iterator when the index equals the size. * Annotate `Collections.emptyIterator()` as `@Unmodifiable`, consistent with `emptyListIterator()` and with the inherited `EmptyIterator.remove()`. * Annotate the `SortedMap` and `NavigableMap` key accessors, and their overrides, as `@Pure` rather than `@SideEffectFree`, matching the `SortedSet` and `NavigableSet` accessors and `ConcurrentSkipListMap`. `firstEntry()` and `lastEntry()` remain `@SideEffectFree` because each call returns a new entry. * Annotate the set views that delegate to those accessors as `@Pure`. * Move `@Modifiable` from the element type to the iterator in `IdentityHashMap.EntrySet.iterator()`. * Fix formatting: merged declarations in `ConcurrentLinkedDeque` and `ListIterator`, trailing whitespace in `ConcurrentNavigableMap`, and missing spaces in `ConcurrentMap` and `NavigableSet`. * Remove redundant imports and an unnecessary `@SuppressWarnings("unchecked")` from `Collections`. * Fix a typo in `README.md`. --- README.md | 2 +- .../share/classes/java/util/AbstractList.java | 2 +- .../share/classes/java/util/ArrayList.java | 4 +- .../share/classes/java/util/Collections.java | 55 ++++++++----------- .../classes/java/util/IdentityHashMap.java | 2 +- .../share/classes/java/util/ListIterator.java | 3 +- .../share/classes/java/util/NavigableMap.java | 9 +-- .../share/classes/java/util/NavigableSet.java | 2 +- .../java/util/ReverseOrderSortedMapView.java | 4 ++ .../java/util/ReverseOrderSortedSetView.java | 4 +- .../share/classes/java/util/SortedMap.java | 4 +- .../share/classes/java/util/TreeMap.java | 20 +++++-- .../concurrent/ConcurrentLinkedDeque.java | 4 +- .../java/util/concurrent/ConcurrentMap.java | 2 +- .../concurrent/ConcurrentNavigableMap.java | 10 ++-- 15 files changed, 68 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 14cfbd568afb..8767fa374a25 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ cp -p $CHECKERFRAMEWORK/checker-qual/build/libs/checker-qual-*-sources.jar check jar tf checker-qual.jar | grep '\.java$' | grep -v 'module-info.java' | sed 's/\/[^/]*\.java/;/' | sed 's/\//./g' | sed 's/^/ exports /' | sort -u ``` -It addition to updating `.java` files, the command will output a list of export +In addition to updating `.java` files, the command will output a list of export lines. Place them in `src/java.base/share/classes/module-info.java`. If no new packages were recently added to the Checker Framework, then likely no changes are needed in the `module-info.java` file. diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index c3f6df8c5c73..f6d173fce222 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -387,7 +387,7 @@ public boolean addAll(@IteratorPolyMod @Growable @GuardSatisfied AbstractList * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty AbstractList this, final @IndexOrHigh({"this"}) int index) { + public @PolyGrowShrink ListIterator listIterator(@PolyGrowShrink AbstractList this, final @IndexOrHigh({"this"}) int index) { rangeCheckForAdd(index); return new ListItr(index); diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index 511fd6f97b4f..9e02fadd00a7 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -1107,7 +1107,7 @@ private void readObject(java.io.ObjectInputStream s) * * @see #listIterator(int) */ - public @PolyGrowShrink @PolyModifiable ListIterator listIterator(@PolyGrowShrink @PolyModifiable ArrayList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ArrayList this) { return new ListItr(0); } @@ -1119,7 +1119,7 @@ private void readObject(java.io.ObjectInputStream s) * @return an iterator over the elements in this list in proper sequence */ @SideEffectFree - public @PolyGrowShrink @PolyModifiable Iterator iterator(@PolyGrowShrink @PolyModifiable ArrayList this) { + public @PolyGrowShrink @PolyModifiable @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty ArrayList this) { return new Itr(); } diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index f58f819e4f39..d2481186965e 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -65,35 +65,6 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Array; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.Collections.AsLIFOQueue; -import java.util.Collections.CheckedCollection; -import java.util.Collections.CheckedList; -import java.util.Collections.CheckedNavigableMap; -import java.util.Collections.CheckedNavigableSet; -import java.util.Collections.CheckedQueue; -import java.util.Collections.CheckedRandomAccessList; -import java.util.Collections.CheckedSet; -import java.util.Collections.CheckedSortedMap; -import java.util.Collections.CheckedSortedSet; -import java.util.Collections.SynchronizedCollection; -import java.util.Collections.SynchronizedList; -import java.util.Collections.SynchronizedNavigableMap; -import java.util.Collections.SynchronizedNavigableSet; -import java.util.Collections.SynchronizedRandomAccessList; -import java.util.Collections.SynchronizedSet; -import java.util.Collections.SynchronizedSortedMap; -import java.util.Collections.SynchronizedSortedSet; -import java.util.Collections.UnmodifiableCollection; -import java.util.Collections.UnmodifiableList; -import java.util.Collections.UnmodifiableNavigableMap; -import java.util.Collections.UnmodifiableNavigableSet; -import java.util.Collections.UnmodifiableRandomAccessList; -import java.util.Collections.UnmodifiableSequencedCollection; -import java.util.Collections.UnmodifiableSequencedSet; -import java.util.Collections.UnmodifiableSet; -import java.util.Collections.UnmodifiableSortedMap; -import java.util.Collections.UnmodifiableSortedSet; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -206,7 +177,6 @@ private Collections() { * found to violate the {@link Comparable} contract * @see List#sort(Comparator) */ - @SuppressWarnings("unchecked") @SideEffectsOnly("#1") public static > void sort(@IteratorPolyMod @Replaceable List list) { list.sort(null); @@ -2355,7 +2325,9 @@ public SortedMap headMap(K toKey) @SideEffectFree public SortedMap tailMap(K fromKey) { return new UnmodifiableSortedMap<>(sm.tailMap(fromKey)); } + @Pure public K firstKey() { return sm.firstKey(); } + @Pure public K lastKey() { return sm.lastKey(); } } @@ -2435,9 +2407,13 @@ public NavigableSet navigableKeySet() UnmodifiableNavigableMap(NavigableMap m) {super(m); nm = m;} + @Pure public @Nullable K lowerKey(K key) { return nm.lowerKey(key); } + @Pure public @Nullable K floorKey(K key) { return nm.floorKey(key); } + @Pure public @Nullable K ceilingKey(K key) { return nm.ceilingKey(key); } + @Pure public @Nullable K higherKey(K key) { return nm.higherKey(key); } @SuppressWarnings("unchecked") @@ -2836,9 +2812,11 @@ public SortedSet tailSet(E fromElement) { } } + @Pure public E first() { synchronized (mutex) {return ss.first();} } + @Pure public E last() { synchronized (mutex) {return ss.last();} } @@ -3473,9 +3451,11 @@ public SortedMap tailMap(K fromKey) { } } + @Pure public K firstKey() { synchronized (mutex) {return sm.firstKey();} } + @Pure public K lastKey() { synchronized (mutex) {return sm.lastKey();} } @@ -3558,18 +3538,22 @@ static class SynchronizedNavigableMap public @Nullable Entry lowerEntry(K key) { synchronized (mutex) { return nm.lowerEntry(key); } } + @Pure public @Nullable K lowerKey(K key) { synchronized (mutex) { return nm.lowerKey(key); } } public @Nullable Entry floorEntry(K key) { synchronized (mutex) { return nm.floorEntry(key); } } + @Pure public @Nullable K floorKey(K key) { synchronized (mutex) { return nm.floorKey(key); } } public @Nullable Entry ceilingEntry(K key) { synchronized (mutex) { return nm.ceilingEntry(key); } } + @Pure public @Nullable K ceilingKey(K key) { synchronized (mutex) { return nm.ceilingKey(key); } } public @Nullable Entry higherEntry(K key) { synchronized (mutex) { return nm.higherEntry(key); } } + @Pure public @Nullable K higherKey(K key) { synchronized (mutex) { return nm.higherKey(key); } } public @Nullable Entry firstEntry() @@ -4047,6 +4031,7 @@ static class CheckedSortedSet extends CheckedSet @Pure public @Nullable Comparator comparator() { return ss.comparator(); } + @Pure public E first() { return ss.first(); } @Pure public E last() { return ss.last(); } @@ -4852,7 +4837,9 @@ static class CheckedSortedMap extends CheckedMap @Pure public @Nullable Comparator comparator() { return sm.comparator(); } + @Pure public K firstKey() { return sm.firstKey(); } + @Pure public K lastKey() { return sm.lastKey(); } @SideEffectFree @@ -4932,7 +4919,9 @@ static class CheckedNavigableMap extends CheckedSortedMap @Pure public @Nullable Comparator comparator() { return nm.comparator(); } + @Pure public K firstKey() { return nm.firstKey(); } + @Pure public K lastKey() { return nm.lastKey(); } public @Nullable Entry lowerEntry(K key) { @@ -4942,6 +4931,7 @@ static class CheckedNavigableMap extends CheckedSortedMap : null; } + @Pure public @Nullable K lowerKey(K key) { return nm.lowerKey(key); } public @Nullable Entry floorEntry(K key) { @@ -4951,6 +4941,7 @@ static class CheckedNavigableMap extends CheckedSortedMap : null; } + @Pure public @Nullable K floorKey(K key) { return nm.floorKey(key); } public @Nullable Entry ceilingEntry(K key) { @@ -4960,6 +4951,7 @@ static class CheckedNavigableMap extends CheckedSortedMap : null; } + @Pure public @Nullable K ceilingKey(K key) { return nm.ceilingKey(key); } public @Nullable Entry higherEntry(K key) { @@ -4969,6 +4961,7 @@ static class CheckedNavigableMap extends CheckedSortedMap : null; } + @Pure public @Nullable K higherKey(K key) { return nm.higherKey(key); } public @Nullable Entry firstEntry() { @@ -5080,7 +5073,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { */ @SuppressWarnings("unchecked") @SideEffectFree - public static @Modifiable Iterator emptyIterator() { + public static @Unmodifiable Iterator emptyIterator() { return (Iterator) EmptyIterator.EMPTY_ITERATOR; } diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 2ed3d81169b2..48cd25d628a8 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -1298,7 +1298,7 @@ public Spliterator spliterator() { private class EntrySet extends AbstractSet> { @SideEffectFree - public Iterator> iterator() { + public @Modifiable Iterator> iterator() { return new EntryIterator(); } @Pure diff --git a/src/java.base/share/classes/java/util/ListIterator.java b/src/java.base/share/classes/java/util/ListIterator.java index bbf723b70a74..5b1aa4d9bd35 100644 --- a/src/java.base/share/classes/java/util/ListIterator.java +++ b/src/java.base/share/classes/java/util/ListIterator.java @@ -223,4 +223,5 @@ public interface ListIterator extends Iterator { @CFComment("Not @EnsuresNonEmpty(this) because this adds *before* the cursor.") @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - void add(@Growable @GuardSatisfied ListIterator this, E e);} + void add(@Growable @GuardSatisfied ListIterator this, E e); +} diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index e2285bc3e5f6..ffaa760cbe16 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -43,6 +43,7 @@ import org.checkerframework.checker.modifiability.qual.Ungrowable; import org.checkerframework.checker.nullness.qual.KeyFor; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; @@ -145,7 +146,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ - @SideEffectFree + @Pure @Nullable K lowerKey(K key); /** @@ -176,7 +177,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ - @SideEffectFree + @Pure @Nullable K floorKey(K key); /** @@ -207,7 +208,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ - @SideEffectFree + @Pure @Nullable K ceilingKey(K key); /** @@ -238,7 +239,7 @@ public interface NavigableMap extends SortedMap { * @throws NullPointerException if the specified key is null * and this map does not permit null keys */ - @SideEffectFree + @Pure @Nullable K higherKey(K key); /** diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 46148cc025ab..9a661d7cebca 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -190,7 +190,7 @@ * @return an iterator over the elements in this set, in ascending order */ @SideEffectFree - @PolyModifiable@PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet this); + @PolyModifiable @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyModifiable @PolyNonEmpty NavigableSet this); /** * Returns a reverse order view of the elements contained in this set. diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 095d952e02de..1169732bad82 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -168,10 +168,12 @@ public SortedMap reversed() { return base; } + @Pure public K firstKey() { return base.lastKey(); } + @Pure public K lastKey() { return base.firstKey(); } @@ -486,10 +488,12 @@ public int size() { return cmp; } + @Pure public K firstKey() { return this.entryIterator().next().getKey(); } + @Pure public K lastKey() { var it = this.entryIterator(); if (! it.hasNext()) diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java index ea3d0cdd238f..385db239437d 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java @@ -365,12 +365,12 @@ public int size() { return ReverseOrderSortedSetView.this.comparator(); } - @SideEffectFree + @Pure public E first() { return this.iterator().next(); } - @SideEffectFree + @Pure public E last() { var it = this.iterator(); if (! it.hasNext()) diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index d431d330faa7..80620c5dc68d 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -236,7 +236,7 @@ * @return the first (lowest) key currently in this map * @throws NoSuchElementException if this map is empty */ - @SideEffectFree + @Pure @KeyFor("this") K firstKey(@GuardSatisfied @NonEmpty SortedMap this); /** @@ -245,7 +245,7 @@ * @return the last (highest) key currently in this map * @throws NoSuchElementException if this map is empty */ - @SideEffectFree + @Pure @KeyFor("this") K lastKey(@GuardSatisfied @NonEmpty SortedMap this); /** diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index d0191927b5cc..3f3cb0bf46ff 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -334,7 +334,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied /** * @throws NoSuchElementException {@inheritDoc} */ - @SideEffectFree + @Pure public @KeyFor("this") K firstKey(@NonEmpty TreeMap this) { return key(getFirstEntry()); } @@ -342,7 +342,7 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied /** * @throws NoSuchElementException {@inheritDoc} */ - @SideEffectFree + @Pure public @KeyFor("this") K lastKey(@NonEmpty TreeMap this) { return key(getLastEntry()); } @@ -1084,7 +1084,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ - @SideEffectFree + @Pure public @Nullable K lowerKey(K key) { return keyOrNull(getLowerEntry(key)); } @@ -1108,7 +1108,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ - @SideEffectFree + @Pure public @Nullable K floorKey(K key) { return keyOrNull(getFloorEntry(key)); } @@ -1132,7 +1132,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ - @SideEffectFree + @Pure public @Nullable K ceilingKey(K key) { return keyOrNull(getCeilingEntry(key)); } @@ -1156,7 +1156,7 @@ public void clear(@Shrinkable @GuardSatisfied TreeMap this) { * does not permit null keys * @since 1.6 */ - @SideEffectFree + @Pure public @Nullable K higherKey(K key) { return keyOrNull(getHigherEntry(key)); } @@ -2044,6 +2044,7 @@ public final boolean containsKey(@UnknownSignedness Object key) { return exportEntry(subCeiling(key)); } + @Pure public final @Nullable K ceilingKey(K key) { return keyOrNull(subCeiling(key)); } @@ -2052,6 +2053,7 @@ public final boolean containsKey(@UnknownSignedness Object key) { return exportEntry(subHigher(key)); } + @Pure public final @Nullable K higherKey(K key) { return keyOrNull(subHigher(key)); } @@ -2060,6 +2062,7 @@ public final boolean containsKey(@UnknownSignedness Object key) { return exportEntry(subFloor(key)); } + @Pure public final @Nullable K floorKey(K key) { return keyOrNull(subFloor(key)); } @@ -2068,14 +2071,17 @@ public final boolean containsKey(@UnknownSignedness Object key) { return exportEntry(subLower(key)); } + @Pure public final @Nullable K lowerKey(K key) { return keyOrNull(subLower(key)); } + @Pure public final K firstKey() { return key(subLowest()); } + @Pure public final K lastKey() { return key(subHighest()); } @@ -2600,7 +2606,9 @@ private Object readResolve() { } @SideEffectFree public Set> entrySet() { throw new InternalError(); } + @Pure public K lastKey() { throw new InternalError(); } + @Pure public K firstKey() { throw new InternalError(); } @SideEffectFree public SortedMap subMap(K fromKey, K toKey) { throw new InternalError(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 534a7143cde9..e001002516ae 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -1048,7 +1048,8 @@ public boolean add(@Growable ConcurrentLinkedDeque this, E e) { @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") - public @Nullable E poll(@Shrinkable @CanShrink ConcurrentLinkedDeque this) { return pollFirst(); } @Pure + public @Nullable E poll(@Shrinkable @CanShrink ConcurrentLinkedDeque this) { return pollFirst(); } + @Pure public @Nullable E peek() { return peekFirst(); } /** @@ -1057,6 +1058,7 @@ public boolean add(@Growable ConcurrentLinkedDeque this, E e) { @SideEffectsOnly("this") @DoesNotUnrefineReceiver("modifiability") public E remove(@Shrinkable @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } + /** * @throws NoSuchElementException {@inheritDoc} */ diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 1fab3cb06327..2cf609428b6e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -128,7 +128,7 @@ public interface ConcurrentMap this,BiConsumer action) { + default void forEach(@MaybeModifiable ConcurrentMap this, BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { K k; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index 88089e87c66f..1eb2448eac2a 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -76,7 +76,7 @@ public interface ConcurrentNavigableMap * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentNavigableMap this, + @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentNavigableMap this, K toKey, boolean inclusive); /** @@ -85,7 +85,7 @@ public interface ConcurrentNavigableMap * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentNavigableMap this, + @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentNavigableMap this, K fromKey, boolean inclusive); /** @@ -94,7 +94,7 @@ public interface ConcurrentNavigableMap * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - @PolyModifiable ConcurrentNavigableMap subMap(@PolyModifiable ConcurrentNavigableMap this, + @PolyModifiable ConcurrentNavigableMap subMap(@PolyModifiable ConcurrentNavigableMap this, K fromKey, K toKey); /** @@ -103,7 +103,7 @@ public interface ConcurrentNavigableMap * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentNavigableMap this, + @PolyModifiable ConcurrentNavigableMap headMap(@PolyModifiable ConcurrentNavigableMap this, K toKey); /** @@ -112,7 +112,7 @@ public interface ConcurrentNavigableMap * @throws IllegalArgumentException {@inheritDoc} */ @SideEffectFree - @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentNavigableMap this, + @PolyModifiable ConcurrentNavigableMap tailMap(@PolyModifiable ConcurrentNavigableMap this, K fromKey); /**