blob: 4283e2fb4f0a4c609c7306ba88c68925253a291a [file] [log] [blame]
package org.checkerframework.checker.index.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;
/**
* The annotated sequence contains a subsequence that is equal to the value of some other
* expression. This annotation permits the Upper Bound Checker to translate indices for one sequence
* into indices for the other sequence.
*
* <p>Consider the following example:
*
* <pre><code>
* class IntSubArray {
* {@literal @}HasSubsequence(subsequence = "this", from = "this.start", to = "this.end")
* int [] array;
* {@literal @}IndexFor("array") int start;
* {@literal @}IndexOrHigh("array") int end;
* }
* </code></pre>
*
* The above annotations mean that the value of an {@code IntSubArray} object is equal to a
* subsequence of its {@code array} field.
*
* <p>These annotations imply the following relationships among {@code @}{@link IndexFor}
* annotations:
*
* <ul>
* <li>If {@code i} is {@code @IndexFor("this")}, then {@code start + i} is
* {@code @IndexFor("array")}.
* <li>If {@code j} is {@code @IndexFor("array")}, then {@code j - start } is
* {@code @IndexFor("this")}.
* </ul>
*
* When assigning an array {@code a} to {@code array}, 4 facts need to be true:
*
* <ul>
* <li>{@code start} is {@code @NonNegative}.
* <li>{@code end} is {@code @LTEqLengthOf("a")}.
* <li>{@code start} is {@code @LessThan("end + 1")}.
* <li>the value of {@code this} equals {@code array[start..end-1]}
* </ul>
*
* The Index Checker verifies the first 3 facts, but always issues a warning because it cannot prove
* the 4th fact. The programmer should should manually verify that the {@code subsequence} field is
* equal to the given subsequence and then suppress the warning.
*
* <p>For an example of how this annotation is used in practice, see the test GuavaPrimitives.java
* in /checker/tests/index/.
*
* <p>This annotation may only be written on fields.
*
* @checker_framework.manual #index-checker Index Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface HasSubsequence {
/** An expression that evaluates to the subsequence. */
@JavaExpression
String subsequence();
/** The index into this where the subsequence starts. */
@JavaExpression
String from();
/** The index into this, immediately past where the subsequence ends. */
@JavaExpression
String to();
}