| // 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)); |
| } |
| } |