diff --git a/checker-qual.jar b/checker-qual.jar index 6fd66597188d..1f4c88a8511f 100644 Binary files a/checker-qual.jar and b/checker-qual.jar differ diff --git a/src/java.base/share/classes/org/checkerframework/checker/builder/qual/CalledMethods.java b/src/java.base/share/classes/org/checkerframework/checker/builder/qual/CalledMethods.java index 8ae314c7fcdb..bc457c6a7979 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/builder/qual/CalledMethods.java +++ b/src/java.base/share/classes/org/checkerframework/checker/builder/qual/CalledMethods.java @@ -21,7 +21,7 @@ /** * The names of methods that have definitely been called. * - * @return the names of methods that have definetely been called + * @return the names of methods that have definitely been called */ String[] value(); } 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 07c28dc621ce..9d76da93e24e 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 @@ -96,7 +96,7 @@ public enum ConversionCategory { /** * Use if no object of any type can be passed as parameter. In this case, the only legal value is - * null. This is seldomly needed, and indicates an error in most cases. For example: + * null. This is seldom needed, and indicates an error in most cases. For example: * *
    *   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");
@@ -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:
@@ -210,6 +211,13 @@ public static ConversionCategory fromConversionChar(char c) {
     throw new IllegalArgumentException("Bad conversion character " + c);
   }
 
+  /**
+   * Converts an array to a set.
+   *
+   * @param a an array
+   * @param  the type of array and set elements
+   * @return a set containing the array's elements
+   */
   private static  Set arrayToSet(E[] a) {
     return new HashSet<>(Arrays.asList(a));
   }
@@ -219,11 +227,12 @@ 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 seldomly needed.
+   * Returns the intersection of two categories. This is seldom needed.
    *
    * 
* @@ -266,15 +275,16 @@ public static ConversionCategory intersect(ConversionCategory a, ConversionCateg return v; } } - throw new RuntimeException(); + throw new RuntimeException("Could not compute intersect(" + a + ", " + b + ")"); } /** 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 seldomly needed. + * Returns the union of two categories. This is seldom needed. * *
* @@ -346,7 +356,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 +368,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..3d99894418eb 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. @@ -90,6 +89,13 @@ public static I18nConversionCategory stringToI18nConversionCategory(String strin throw new IllegalArgumentException("Invalid format type " + string); } + /** + * Converts an array to a set. + * + * @param a an array + * @param the type of array and set elements + * @return a set containing the array's elements + */ private static Set arrayToSet(E[] a) { return new HashSet<>(Arrays.asList(a)); } @@ -104,8 +110,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. @@ -147,7 +152,7 @@ public static I18nConversionCategory intersect( return v; } } - throw new RuntimeException(); + throw new RuntimeException("Could not compute intersect(" + a + ", " + b + ")"); } /** 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/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/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/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/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/optional/qual/RequiresPresent.java b/src/java.base/share/classes/org/checkerframework/checker/optional/qual/RequiresPresent.java index d8754d3beacb..1ad847e9e0ae 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/optional/qual/RequiresPresent.java +++ b/src/java.base/share/classes/org/checkerframework/checker/optional/qual/RequiresPresent.java @@ -63,7 +63,7 @@ public @interface RequiresPresent { /** - * The Java expressions that that need to be {@link Present}. + * The Java expressions that need to be {@link Present}. * * @return the Java expressions that need to be {@link Present} * @checker_framework.manual #java-expressions-as-arguments Syntax of Java expressions 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/signature/qual/BinaryName.java b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/BinaryName.java index c178d9371fff..72e3272bdc50 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/BinaryName.java +++ b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/BinaryName.java @@ -9,7 +9,7 @@ /** * Represents a binary name as defined in the Java Language + * href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-13.html#jls-13.1">Java Language * Specification, section 13.1. * *

For example, in diff --git a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/CanonicalName.java b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/CanonicalName.java index b22307594d81..946f216518d2 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/CanonicalName.java +++ b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/CanonicalName.java @@ -12,11 +12,10 @@ * Every canonical name is a fully-qualified name, but not every fully-qualified name is a canonical * name. * - *

JLS section + *

JLS section * 6.7 gives the following example: * *

- * * The difference between a fully qualified name and a canonical name can be seen in code such as: * *
{@code
@@ -27,7 +26,6 @@
  *
  * Both {@code p.O1.I} and {@code p.O2.I} are fully qualified names that denote the member class
  * {@code I}, but only {@code p.O1.I} is its canonical name.
- *
  * 
* * Given a character sequence that is a fully-qualified name, there is no way to know whether or not diff --git a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/FullyQualifiedName.java b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/FullyQualifiedName.java index 9ed69097a969..6d2fcd7b7c5c 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/signature/qual/FullyQualifiedName.java +++ b/src/java.base/share/classes/org/checkerframework/checker/signature/qual/FullyQualifiedName.java @@ -10,7 +10,7 @@ /** * A sequence of dot-separated identifiers, followed by any number of array square brackets. * Represents a fully-qualified name as defined in the Java Language + * href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-6.html#jls-6.7">Java Language * Specification, section 6.7. * *

Examples: 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/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/common/reflection/qual/ClassBound.java b/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassBound.java index 0cae3ff79e33..45bf1d9b9740 100644 --- a/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassBound.java +++ b/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassBound.java @@ -19,7 +19,7 @@ @SubtypeOf({UnknownClass.class}) public @interface ClassBound { /** - * The binary + * The binary * name of the class or classes that upper-bound the values of this Class object. */ String[] value(); diff --git a/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassVal.java b/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassVal.java index 424efe40bb8f..a6d22b0bc4ce 100644 --- a/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassVal.java +++ b/src/java.base/share/classes/org/checkerframework/common/reflection/qual/ClassVal.java @@ -22,7 +22,7 @@ /** * The name of the type that this Class object represents. The name is a "fully-qualified binary * name" ({@link org.checkerframework.checker.signature.qual.FqBinaryName}): a primitive or binary name, + * href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-13.html#jls-13.1">binary name, * possibly followed by some number of array brackets. * * @return the name of the type that this Class object represents diff --git a/src/java.base/share/classes/org/checkerframework/common/reflection/qual/MethodVal.java b/src/java.base/share/classes/org/checkerframework/common/reflection/qual/MethodVal.java index 3c7612321b0c..792119ad09e7 100644 --- a/src/java.base/share/classes/org/checkerframework/common/reflection/qual/MethodVal.java +++ b/src/java.base/share/classes/org/checkerframework/common/reflection/qual/MethodVal.java @@ -24,7 +24,7 @@ @SubtypeOf({UnknownMethod.class}) public @interface MethodVal { /** - * The binary + * The binary * name of the class that declares this method. */ String[] className(); 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 {} diff --git a/src/java.base/share/classes/org/checkerframework/dataflow/qual/Pure.java b/src/java.base/share/classes/org/checkerframework/dataflow/qual/Pure.java index 82cdb5968795..3409465840f4 100644 --- a/src/java.base/share/classes/org/checkerframework/dataflow/qual/Pure.java +++ b/src/java.base/share/classes/org/checkerframework/dataflow/qual/Pure.java @@ -25,13 +25,4 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) -public @interface Pure { - /** The type of purity. */ - public static enum Kind { - /** The method has no visible side effects. */ - SIDE_EFFECT_FREE, - - /** The method returns exactly the same value when called in the same environment. */ - DETERMINISTIC - } -} +public @interface Pure {} 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 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 index ab6a7dd1718f..cb06cb25f51d 100644 --- a/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java +++ b/src/java.base/share/classes/org/checkerframework/dataflow/qual/SideEffectsOnly.java @@ -8,12 +8,27 @@ 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. + * A method annotated with the declaration annotation {@code @SideEffectsOnly({"A", "B"})} changes + * the value of at most the expressions A and B. No other expression is directly modified by the + * method. Absent aliasing, no other expression has a different value after a call to the method. + * But checking of this annotation (under {@code -AcheckPurityAnnotations}) treats two expressions + * as possibly aliased only when an assignment relating them appears in the method body. * - * @checker_framework.manual #type-refinement-purity Specifying side effects + *

This annotation is inherited by subtypes, just as if it were meta-annotated with + * {@code @InheritedAnnotation}. + * + *

On a constructor, this annotation constrains what the constructor modifies besides the object + * being constructed. Assigning to the new object's own fields is always permitted and need not be + * listed, because the object did not exist before the call; writing {@code this} in the annotation + * is legal but has no additional effect. At a {@code new} expression, the expressions that are + * reached through {@code this} are ignored, because the object being constructed did not exist + * before the call. A constructor's annotation does not yet affect type refinement at {@code new} + * expressions. + * + * @checker_framework.manual #side-effects-only-checking Checking {@code @SideEffectsOnly} */ +// @InheritedAnnotation cannot be written here, because "dataflow" project cannot depend on +// "framework" project. @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) @@ -21,9 +36,16 @@ /** * An upper bound on the expressions that this method might change the value of. * + *

Each expression must denote the same location every time it is evaluated: it must be a + * variable, a field access, an array access, a literal, a class name, or a call to a {@link Pure} + * method, recursively. A {@code @Pure} method returns the same value every time it is called with + * the same arguments, so a call to one qualifies so long as its receiver and its arguments do. An + * expression such as {@code "#1.getList()"}, where {@code getList} is not {@code @Pure}, may + * denote a different value each time it is evaluated, so no method body could satisfy it. + * * @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(); + String[] value(); } diff --git a/src/java.base/share/classes/org/checkerframework/framework/qual/ConditionalPostconditionAnnotation.java b/src/java.base/share/classes/org/checkerframework/framework/qual/ConditionalPostconditionAnnotation.java index 9b7feb69237b..0a158a141c1f 100644 --- a/src/java.base/share/classes/org/checkerframework/framework/qual/ConditionalPostconditionAnnotation.java +++ b/src/java.base/share/classes/org/checkerframework/framework/qual/ConditionalPostconditionAnnotation.java @@ -37,11 +37,12 @@ *


  * {@literal @}ConditionalPostconditionAnnotation(qualifier = MinLen.class)
  * {@literal @}Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
- * public {@literal @}interface EnsuresMinLen {
+ * public {@literal @}interface EnsuresMinLenIf {
  *   String[] expression();
  *   boolean result();
  *   {@literal @}QualifierArgument("value")
  *   int targetValue() default 0;
+ * }
  * 
* * The {@code expression} element holds the expressions to which the qualifier applies and {@code @@ -52,7 +53,7 @@ * {@code @MinLen(4)} upon returning {@code true}. * *

- * {@literal @}EnsuresMinLenIf(expression = "field", result = true, targetValue = 4")
+ * {@literal @}EnsuresMinLenIf(expression = "field", result = true, targetValue = 4)
  * public boolean isFieldBool() {
  *   return field == "true" || field == "false";
  * }
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 {