Skip to content

Commit 2c7cc61

Browse files
authored
Add test cases for unnamed patterns and variables
1 parent d2f5e23 commit 2c7cc61

File tree

4 files changed

+183
-3
lines changed

4 files changed

+183
-3
lines changed

framework-test/src/main/java/org/checkerframework/framework/test/TestUtilities.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public class TestUtilities {
6161
/** True if the JVM is version 21 or above. */
6262
public static final boolean IS_AT_LEAST_21_JVM = SystemUtil.jreVersion >= 21;
6363

64+
/** True if the JVM is version 22 or above. */
65+
public static final boolean IS_AT_LEAST_22_JVM = SystemUtil.jreVersion >= 22;
66+
6467
static {
6568
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
6669
OutputStream err = new ByteArrayOutputStream();
@@ -261,7 +264,9 @@ public static boolean isJavaTestFile(File file) {
261264
|| (!IS_AT_MOST_17_JVM && nextLine.contains("@above-java17-jdk-skip-test"))
262265
|| (!IS_AT_LEAST_18_JVM && nextLine.contains("@below-java18-jdk-skip-test"))
263266
|| (!IS_AT_MOST_18_JVM && nextLine.contains("@above-java18-jdk-skip-test"))
264-
|| (!IS_AT_LEAST_21_JVM && nextLine.contains("@below-java21-jdk-skip-test"))) {
267+
|| (!IS_AT_LEAST_21_JVM && nextLine.contains("@below-java21-jdk-skip-test"))
268+
|| (!IS_AT_LEAST_22_JVM && nextLine.contains("@below-java22-jdk-skip-test"))) {
269+
265270
return false;
266271
}
267272
}

framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,8 @@ protected void testJointJavacJavaParserVisitor() {
421421
if (root == null
422422
|| !ajavaChecks
423423
// TODO: Make annotation insertion work for Java 21.
424-
|| root.getSourceFile().toUri().toString().contains("java21")) {
424+
|| root.getSourceFile().toUri().toString().contains("java21")
425+
|| root.getSourceFile().toUri().toString().contains("java22")) {
425426
return;
426427
}
427428

@@ -470,7 +471,8 @@ protected void testAnnotationInsertion() {
470471
if (root == null
471472
|| !ajavaChecks
472473
// TODO: Make annotation insertion work for Java 21.
473-
|| root.getSourceFile().toUri().toString().contains("java21")) {
474+
|| root.getSourceFile().toUri().toString().contains("java21")
475+
|| root.getSourceFile().toUri().toString().contains("java22")) {
474476
return;
475477
}
476478

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @below-java22-jdk-skip-test
2+
3+
// None of the WPI formats supports the new Java 22 languages features, so skip inference until they
4+
// do.
5+
// @infer-jaifs-skip-test
6+
// @infer-ajava-skip-test
7+
// @infer-stubs-skip-test
8+
public class UnnamedPattern {
9+
10+
public sealed interface IntOrBool {}
11+
12+
public record WrappedInt(int a) implements IntOrBool {}
13+
14+
public record WrappedBoolean(boolean b) implements IntOrBool {}
15+
16+
public int test(IntOrBool i) {
17+
int x = 0;
18+
return switch (i) {
19+
case WrappedInt(_) -> {
20+
x = x + 1;
21+
yield x;
22+
}
23+
case WrappedBoolean(_) -> {
24+
x = x + 2;
25+
yield x;
26+
}
27+
};
28+
}
29+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import java.io.FileReader;
2+
import java.io.IOException;
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.NoSuchElementException;
7+
import java.util.Queue;
8+
import java.util.function.Function;
9+
import java.util.stream.Collectors;
10+
11+
// Examples taken from
12+
// https://docs.oracle.com/en/java/javase/24/language/unnamed-variables-and-patterns.html
13+
// @below-java22-jdk-skip-test
14+
15+
// None of the WPI formats supports the new Java 22 languages features, so skip inference until they
16+
// do.
17+
// @infer-jaifs-skip-test
18+
// @infer-ajava-skip-test
19+
// @infer-stubs-skip-test
20+
public class UnnamedVars {
21+
22+
void example1() {
23+
int[] orderIDs = {34, 45, 23, 27, 15};
24+
int total = 0;
25+
for (int _ : orderIDs) {
26+
total++;
27+
}
28+
System.out.println("Total: " + total);
29+
}
30+
31+
record Caller(String phoneNumber) {}
32+
33+
static List<Object> everyFifthCaller(Queue<Caller> q, int prizes) {
34+
var winners = new ArrayList<>();
35+
try {
36+
while (prizes > 0) {
37+
Caller _ = q.remove();
38+
Caller _ = q.remove();
39+
Caller _ = q.remove();
40+
Caller _ = q.remove();
41+
winners.add(q.remove());
42+
prizes--;
43+
}
44+
} catch (NoSuchElementException _) {
45+
// Do nothing
46+
}
47+
return winners;
48+
}
49+
50+
static void doesFileExist(String path) {
51+
try (var _ = new FileReader(path)) {
52+
// Do nothing
53+
} catch (IOException e) {
54+
e.printStackTrace();
55+
}
56+
}
57+
58+
void example2() {
59+
Function<String, Integer> sideEffect =
60+
s -> {
61+
System.out.println(s);
62+
return 0;
63+
};
64+
65+
for (int i = 0, _ = sideEffect.apply("Starting for-loop"); i < 10; i++) {
66+
System.out.println(i);
67+
}
68+
}
69+
70+
static void stringLength(String s) {
71+
int len = 0;
72+
for (char _ : s.toCharArray()) {
73+
len++;
74+
}
75+
System.out.println("Length of " + s + ": " + len);
76+
}
77+
78+
static void validateNumber(String s) {
79+
try {
80+
int i = Integer.parseInt(s);
81+
System.out.println(i + " is valid");
82+
} catch (NumberFormatException _) {
83+
System.out.println(s + " isn't valid");
84+
}
85+
}
86+
87+
record Point(double x, double y) {}
88+
89+
record UniqueRectangle(String id, Point upperLeft, Point lowerRight) {}
90+
91+
static Map<String, String> getIDs(List<UniqueRectangle> r) {
92+
return r.stream().collect(Collectors.toMap(UniqueRectangle::id, _ -> "NODATA"));
93+
}
94+
95+
enum Color {
96+
RED,
97+
GREEN,
98+
BLUE
99+
}
100+
101+
record ColoredPoint(Point p, Color c) {}
102+
103+
double getDistance(Object obj1, Object obj2) {
104+
if (obj1 instanceof ColoredPoint(Point p1, _) && obj2 instanceof ColoredPoint(Point p2, _)) {
105+
return java.lang.Math.sqrt(
106+
java.lang.Math.pow(p2.x - p1.x, 2) + java.lang.Math.pow(p2.y - p1.y, 2));
107+
} else {
108+
return -1;
109+
}
110+
}
111+
112+
double getDistance2(Object obj1, Object obj2) {
113+
if (obj1 instanceof ColoredPoint(Point p1, Color _)
114+
&& obj2 instanceof ColoredPoint(Point p2, Color _)) {
115+
return java.lang.Math.sqrt(
116+
java.lang.Math.pow(p2.x - p1.x, 2) + java.lang.Math.pow(p2.y - p1.y, 2));
117+
} else {
118+
return -1;
119+
}
120+
}
121+
122+
sealed interface Employee permits Salaried, Freelancer, Intern {}
123+
124+
record Salaried(String name, long salary) implements Employee {}
125+
126+
record Freelancer(String name) implements Employee {}
127+
128+
record Intern(String name) implements Employee {}
129+
130+
void printSalary(Employee b) {
131+
switch (b) {
132+
case Salaried r -> System.out.println("Salary: " + r.salary());
133+
case Freelancer _ -> System.out.println("Other");
134+
case Intern _ -> System.out.println("Other");
135+
}
136+
}
137+
138+
void printSalary2(Employee b) {
139+
switch (b) {
140+
case Salaried r -> System.out.println("Salary: " + r.salary());
141+
case Freelancer _, Intern _ -> System.out.println("Other");
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)