import org.checkerframework.common.value.qual.*; class ArrayInit { public void raggedArrays() { int @ArrayLen(4) [] @ArrayLen({1, 3, 4}) [] @ArrayLen({1, 2, 3, 4, 7}) [] alpha = new int[][][] { {{1, 1}, {1, 1, 1}, {1}, {1}}, {{1}, {1}, {1}, {1, 1}}, {{1, 2, 3, 4, 5, 6, 7}}, {{1}, {1}, {1, 1, 1, 1}} }; int @ArrayLen(4) [] @ArrayLen({1, 3, 4}) [] @ArrayLenRange(from = 1, to = 12) [] gamma = new int[][][] { {{1, 1}, {1, 1, 1}, {1}, {1}}, {{1}, {1}, {1}, {1, 1}}, {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}, {{1}, {1}, {1, 1, 1, 1}} }; int @ArrayLen(4) [] @ArrayLen({1, 2, 3}) [] a = {{1, 1}, {1, 1, 1}, {1}, {1}}; int @ArrayLen(4) [] @ArrayLen({1, 2}) [] b = {{1}, {1}, {1}, {1, 1}}; int @ArrayLen(1) [] @ArrayLen(7) [] c = {{1, 2, 3, 4, 5, 6, 7}}; int @ArrayLen(3) [] @ArrayLen({1, 4}) [] d = {{1}, {1}, {1, 1, 1, 1}}; int @ArrayLen(4) [] @ArrayLen({1, 3, 4}) [] @ArrayLen({1, 2, 3, 4, 7}) [] beta = { a, b, c, d }; int @ArrayLen(4) [] @ArrayLen({1, 2, 3}) [] a1 = {{1, 1}, {1, 1, 1}, {1}, {1}}; int @ArrayLen(4) [] @ArrayLen({1, 2}) [] b1 = {{1}, {1}, {1}, {1, 1}}; int @ArrayLen(1) [] @ArrayLen(11) [] c1 = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; int @ArrayLen(3) [] @ArrayLen({1, 4}) [] d1 = {{1}, {1}, {1, 1, 1, 1}}; int @ArrayLen(4) [] @ArrayLenRange(from = 1, to = 4) [] @ArrayLenRange(from = 1, to = 11) [] delta = {a1, b1, c1, d1}; } public void numberInit() { int @ArrayLen({1}) [] a = new int[1]; } public void listInit() { int @ArrayLen({1}) [] a = new int[] {4}; } public void varInit() { int i = 1; int @ArrayLen({1}) [] a = new int[i]; } public void rangeInit( @IntRange(from = 1, to = 2) int shortLength, @IntRange(from = 1, to = 20) int longLength, @BottomVal int bottom) { int @ArrayLen({1, 2}) [] a = new int[shortLength]; //:: error: (assignment.type.incompatible) int @ArrayLen({1, 2}) [] b = new int[longLength]; int @ArrayLenRange(from = 1, to = 20) [] d = new int[longLength]; int @ArrayLen({0}) [] c = new int[bottom]; } public void multiDim() { int i = 2; int j = 3; int @ArrayLen({2}) [] @ArrayLen({3}) [] a = new int[2][3]; int @ArrayLen({2}) [] @ArrayLen({3}) [] b = new int[i][j]; int @ArrayLen({2}) [][] c = new int[][] {{2}, {3}}; } public void initilizer() { int @ArrayLen(3) [] ints = new int[] {2, 2, 2}; byte @StringVal("d%") [] bytes = new byte[] {100, '%'}; char @StringVal("-A%") [] chars = new char[] {45, 'A', '%'}; int @ArrayLen(3) [] ints2 = {2, 2, 2}; } public void vargsTest() { // type of arg should be @UnknownVal Object @BottomVal[] vargs((Object[]) null); // type of arg should be @UnknownVal int @BottomVal[] vargs((int[]) null); // type of arg should be @UnknownVal byte @BottomVal[] vargs((byte[]) null); } public void vargs(Object @ArrayLen(0) ... ints) {} public void nullableArrays() { Object @ArrayLen(2) [] @ArrayLen(1) [] o = new Object[][] {new Object[] {null}, null}; Object @ArrayLen(1) [][] o2 = new Object[][] {null}; Object @ArrayLen(1) [] @ArrayLen(1) [] o3 = new Object[][] {null}; } public void subtyping1(int @ArrayLen({1, 5}) [] a) { int @ArrayLenRange(from = 1, to = 5) [] b = a; //:: error: (assignment.type.incompatible) int @ArrayLenRange(from = 2, to = 5) [] c = a; } public void subtyping2(int @ArrayLenRange(from = 1, to = 5) [] a) { int @ArrayLen({1, 2, 3, 4, 5}) [] b = a; //:: error: (assignment.type.incompatible) int @ArrayLen({1, 5}) [] c = a; } public void subtyping3(int @ArrayLenRange(from = 1, to = 17) [] a) { //:: error: (assignment.type.incompatible) int @ArrayLenRange(from = 1, to = 12) [] b = a; //:: error: (assignment.type.incompatible) int @ArrayLenRange(from = 5, to = 18) [] c = a; int @ArrayLenRange(from = 0, to = 20) [] d = a; } public void lub1(boolean flag, @IntRange(from = 1, to = 200) int x) { int[] a; if (flag) { a = new int[x]; } else { a = new int[250]; } int @ArrayLenRange(from = 1, to = 250) [] b = a; } public void lub2( boolean flag, @IntRange(from = 1, to = 20) int x, @IntRange(from = 50, to = 75) int y) { int[] a; if (flag) { a = new int[x]; } else { a = new int[y]; } int @ArrayLenRange(from = 1, to = 75) [] b = a; } public void lub3( boolean flag, @IntRange(from = 1, to = 5) int x, @IntRange(from = 3, to = 7) int y) { int[] a; if (flag) { a = new int[x]; } else { a = new int[y]; } int @ArrayLenRange(from = 1, to = 7) [] b = a; int @ArrayLen({1, 2, 3, 4, 5, 6, 7}) [] c = a; } public void refine(int[] q) { if (q.length < 20) { @IntRange(from = 0, to = 19) int x = q.length; int @ArrayLenRange(from = 0, to = 19) [] b = q; if (q.length < 5) { int @ArrayLen({0, 1, 2, 3, 4}) [] c = q; } } } // The argument is an arraylen with too many values. //:: warning: (too.many.values.given) public void coerce(int @ArrayLen({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 36}) [] a) { int @ArrayLenRange(from = 1, to = 36) [] b = a; if (a.length < 15) { //:: error: (assignment.type.incompatible) int @ArrayLen({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) [] c = a; } } public void warnings() { //:: warning: (negative.arraylen) int @ArrayLenRange(from = -1, to = 5) [] a; //:: error: (from.greater.than.to) int @ArrayLenRange(from = 10, to = 3) [] b; } }