blob: 06f66cbb06951627cbf984443a7e8070f2178bc1 [file] [log] [blame]
// This test ensures that annotations on different component types of multidimensional arrays
// are printed correctly.
import java.util.List;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.Sibling1;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.Sibling2;
import org.checkerframework.checker.testchecker.wholeprograminference.qual.SiblingWithFields;
import org.checkerframework.common.aliasing.qual.MaybeAliased;
import org.checkerframework.common.aliasing.qual.NonLeaked;
import org.checkerframework.common.aliasing.qual.Unique;
public class MultiDimensionalArrays {
// two dimensional arrays
void requiresS1S2(@Sibling1 int @Sibling2 [] x) {}
int[] twoDimArray;
void testField() {
// :: warning: argument
requiresS1S2(twoDimArray);
}
void useField(@Sibling1 int @Sibling2 [] x) {
twoDimArray = x;
}
void testParam(int[] x) {
// :: warning: argument
requiresS1S2(x);
}
void useParam(@Sibling1 int @Sibling2 [] x) {
testParam(x);
}
int[] useReturn(@Sibling1 int @Sibling2 [] x) {
return x;
}
void testReturn() {
requiresS1S2(
// :: warning: argument
useReturn(
// :: warning: argument
twoDimArray));
}
// three dimensional arrays
void requiresS1S2S1(@Sibling1 int @Sibling2 [] @Sibling1 [] x) {}
int[][] threeDimArray;
void testField2() {
// :: warning: argument
requiresS1S2S1(threeDimArray);
}
void useField2(@Sibling1 int @Sibling2 [] @Sibling1 [] x) {
threeDimArray = x;
}
void testParam2(int[][] x) {
// :: warning: argument
requiresS1S2S1(x);
}
void useParam2(@Sibling1 int @Sibling2 [] @Sibling1 [] x) {
testParam2(x);
}
int[][] useReturn2(@Sibling1 int @Sibling2 [] @Sibling1 [] x) {
return x;
}
void testReturn2() {
// :: warning: argument
requiresS1S2S1(useReturn2(threeDimArray));
}
// three dimensional array with annotations only on two inner types
void requiresS1S2N(@Sibling1 int @Sibling2 [][] x) {}
int[][] threeDimArray2;
void testField3() {
// :: warning: argument
requiresS1S2N(threeDimArray2);
}
void useField3(@Sibling1 int @Sibling2 [][] x) {
threeDimArray2 = x;
}
void testParam3(int[][] x) {
// :: warning: argument
requiresS1S2N(x);
}
void useParam3(@Sibling1 int @Sibling2 [][] x) {
testParam3(x);
}
int[][] useReturn3(@Sibling1 int @Sibling2 [][] x) {
return x;
}
void testReturn3() {
// :: warning: argument
requiresS1S2N(useReturn3(threeDimArray2));
}
// three dimensional array with annotations only on two array types, not innermost type
void requiresS2S1(int @Sibling2 [] @Sibling1 [] x) {}
int[][] threeDimArray3;
void testField4() {
// :: warning: argument
requiresS2S1(threeDimArray3);
}
void useField4(int @Sibling2 [] @Sibling1 [] x) {
threeDimArray3 = x;
}
void testParam4(int[][] x) {
// :: warning: argument
requiresS2S1(x);
}
void useParam4(int @Sibling2 [] @Sibling1 [] x) {
testParam4(x);
}
int[][] useReturn4(int @Sibling2 [] @Sibling1 [] x) {
return x;
}
void testReturn4() {
// :: warning: argument
requiresS2S1(useReturn4(threeDimArray3));
}
// three-dimensional arrays with arguments in annotations
void requiresSf1Sf2Sf3(
@SiblingWithFields(value = {"test1", "test1"}) int @SiblingWithFields(value = {"test2", "test2"}) []
@SiblingWithFields(value = {"test3"}) []
x) {}
int[][] threeDimArray4;
void testField5() {
// :: warning: argument
requiresSf1Sf2Sf3(threeDimArray4);
}
void useField5(
@SiblingWithFields(value = {"test1", "test1"}) int @SiblingWithFields(value = {"test2", "test2"}) []
@SiblingWithFields(value = {"test3"}) []
x) {
threeDimArray4 = x;
}
void testParam5(int[][] x) {
// :: warning: argument
requiresSf1Sf2Sf3(x);
}
void useParam5(
@SiblingWithFields(value = {"test1", "test1"}) int @SiblingWithFields(value = {"test2", "test2"}) []
@SiblingWithFields(value = {"test3"}) []
x) {
testParam5(x);
}
int[][] useReturn5(
@SiblingWithFields(value = {"test1", "test1"}) int @SiblingWithFields(value = {"test2", "test2"}) []
@SiblingWithFields(value = {"test3"}) []
x) {
return x;
}
void testReturn5() {
// :: warning: argument
requiresSf1Sf2Sf3(useReturn5(threeDimArray4));
}
// three dimensional array with annotations from other hierarchies that ought to be preserved
int[][] threeDimArray5;
void testField6() {
// :: warning: argument
requiresS1S2S1(threeDimArray5);
}
void useField6(@Sibling1 @Unique int @Sibling2 @NonLeaked [] @Sibling1 @MaybeAliased [] x) {
threeDimArray5 = x;
}
void testParam6(int[][] x) {
// :: warning: argument
requiresS1S2S1(x);
}
void useParam6(@Sibling1 @Unique int @Sibling2 @NonLeaked [] @Sibling1 @MaybeAliased [] x) {
testParam6(x);
}
int[][] useReturn6(@Sibling1 @Unique int @Sibling2 @NonLeaked [] @Sibling1 @MaybeAliased [] x) {
return x;
}
void testReturn6() {
// :: warning: argument
requiresS1S2S1(useReturn6(threeDimArray));
}
// Shenanigans with lists + arrays; commented out annotations can't be inferred by either
// jaif or stub based WPI for now due to limitations in generics inference.
List<String[]>[] arrayofListsOfStringArrays;
void testField7() {
// :: warning: argument
requiresS1S2L(arrayofListsOfStringArrays);
}
void requiresS1S2L(@Sibling1 List</*@Sibling1*/ String /*@Sibling2*/ []> @Sibling2 [] la) {}
void useField7(@Sibling1 List</*@Sibling1*/ String /*@Sibling2*/ []> @Sibling2 [] x) {
arrayofListsOfStringArrays = x;
}
void testParam7(List<String[]>[] x) {
// :: warning: argument
requiresS1S2L(x);
}
void useParam7(@Sibling1 List</*@Sibling1*/ String /*@Sibling2*/ []> @Sibling2 [] x) {
testParam7(x);
}
List<String[]>[] useReturn7(@Sibling1 List</*@Sibling1*/ String /*@Sibling2*/ []> @Sibling2 [] x) {
return x;
}
void testReturn7() {
// :: warning: argument
requiresS1S2L(useReturn7(arrayofListsOfStringArrays));
}
}