Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/invoke/MethodHandles/TestTableSwitch.java
41152 views
1
/*
2
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @run testng/othervm -Xverify:all TestTableSwitch
27
*/
28
29
import org.testng.annotations.DataProvider;
30
import org.testng.annotations.Test;
31
32
import javax.management.ObjectName;
33
import java.lang.invoke.MethodHandle;
34
import java.lang.invoke.MethodHandles;
35
import java.lang.invoke.MethodType;
36
import java.util.ArrayList;
37
import java.util.List;
38
import java.util.function.IntConsumer;
39
import java.util.function.IntFunction;
40
41
import static org.testng.Assert.assertEquals;
42
43
public class TestTableSwitch {
44
45
static final MethodHandle MH_IntConsumer_accept;
46
static final MethodHandle MH_check;
47
48
static {
49
try {
50
MethodHandles.Lookup lookup = MethodHandles.lookup();
51
MH_IntConsumer_accept = lookup.findVirtual(IntConsumer.class, "accept",
52
MethodType.methodType(void.class, int.class));
53
MH_check = lookup.findStatic(TestTableSwitch.class, "check",
54
MethodType.methodType(void.class, List.class, Object[].class));
55
} catch (ReflectiveOperationException e) {
56
throw new ExceptionInInitializerError(e);
57
}
58
}
59
60
public static MethodHandle simpleTestCase(String value) {
61
return simpleTestCase(String.class, value);
62
}
63
64
public static MethodHandle simpleTestCase(Class<?> type, Object value) {
65
return MethodHandles.dropArguments(MethodHandles.constant(type, value), 0, int.class);
66
}
67
68
public static Object testValue(Class<?> type) {
69
if (type == String.class) {
70
return "X";
71
} else if (type == byte.class) {
72
return (byte) 42;
73
} else if (type == short.class) {
74
return (short) 84;
75
} else if (type == char.class) {
76
return 'Y';
77
} else if (type == int.class) {
78
return 168;
79
} else if (type == long.class) {
80
return 336L;
81
} else if (type == float.class) {
82
return 42F;
83
} else if (type == double.class) {
84
return 84D;
85
} else if (type == boolean.class) {
86
return true;
87
}
88
return null;
89
}
90
91
static final Class<?>[] TEST_TYPES = {
92
Object.class,
93
String.class,
94
byte.class,
95
short.class,
96
char.class,
97
int.class,
98
long.class,
99
float.class,
100
double.class,
101
boolean.class
102
};
103
104
public static Object[] testArguments(int caseNum, List<Object> testValues) {
105
Object[] args = new Object[testValues.size() + 1];
106
args[0] = caseNum;
107
int insertPos = 1;
108
for (Object testValue : testValues) {
109
args[insertPos++] = testValue;
110
}
111
return args;
112
}
113
114
@DataProvider
115
public static Object[][] nonVoidCases() {
116
List<Object[]> tests = new ArrayList<>();
117
118
for (Class<?> returnType : TEST_TYPES) {
119
for (int numCases = 1; numCases < 5; numCases++) {
120
tests.add(new Object[] { returnType, numCases, List.of() });
121
tests.add(new Object[] { returnType, numCases, List.of(TEST_TYPES) });
122
}
123
}
124
125
return tests.toArray(Object[][]::new);
126
}
127
128
private static void check(List<Object> testValues, Object[] collectedValues) {
129
assertEquals(collectedValues, testValues.toArray());
130
}
131
132
@Test(dataProvider = "nonVoidCases")
133
public void testNonVoidHandles(Class<?> type, int numCases, List<Class<?>> additionalTypes) throws Throwable {
134
MethodHandle collector = MH_check;
135
List<Object> testArguments = new ArrayList<>();
136
collector = MethodHandles.insertArguments(collector, 0, testArguments);
137
collector = collector.asCollector(Object[].class, additionalTypes.size());
138
139
Object defaultReturnValue = testValue(type);
140
MethodHandle defaultCase = simpleTestCase(type, defaultReturnValue);
141
defaultCase = MethodHandles.collectArguments(defaultCase, 1, collector);
142
Object[] returnValues = new Object[numCases];
143
MethodHandle[] cases = new MethodHandle[numCases];
144
for (int i = 0; i < cases.length; i++) {
145
Object returnValue = testValue(type);
146
returnValues[i] = returnValue;
147
MethodHandle theCase = simpleTestCase(type, returnValue);
148
theCase = MethodHandles.collectArguments(theCase, 1, collector);
149
cases[i] = theCase;
150
}
151
152
MethodHandle mhSwitch = MethodHandles.tableSwitch(
153
defaultCase,
154
cases
155
);
156
157
for (Class<?> additionalType : additionalTypes) {
158
testArguments.add(testValue(additionalType));
159
}
160
161
assertEquals(mhSwitch.invokeWithArguments(testArguments(-1, testArguments)), defaultReturnValue);
162
163
for (int i = 0; i < numCases; i++) {
164
assertEquals(mhSwitch.invokeWithArguments(testArguments(i, testArguments)), returnValues[i]);
165
}
166
167
assertEquals(mhSwitch.invokeWithArguments(testArguments(numCases, testArguments)), defaultReturnValue);
168
}
169
170
@Test
171
public void testVoidHandles() throws Throwable {
172
IntFunction<MethodHandle> makeTestCase = expectedIndex -> {
173
IntConsumer test = actualIndex -> assertEquals(actualIndex, expectedIndex);
174
return MH_IntConsumer_accept.bindTo(test);
175
};
176
177
MethodHandle mhSwitch = MethodHandles.tableSwitch(
178
/* default: */ makeTestCase.apply(-1),
179
/* case 0: */ makeTestCase.apply(0),
180
/* case 1: */ makeTestCase.apply(1),
181
/* case 2: */ makeTestCase.apply(2)
182
);
183
184
mhSwitch.invokeExact((int) -1);
185
mhSwitch.invokeExact((int) 0);
186
mhSwitch.invokeExact((int) 1);
187
mhSwitch.invokeExact((int) 2);
188
}
189
190
@Test(expectedExceptions = NullPointerException.class)
191
public void testNullDefaultHandle() {
192
MethodHandles.tableSwitch(null, simpleTestCase("test"));
193
}
194
195
@Test(expectedExceptions = NullPointerException.class)
196
public void testNullCases() {
197
MethodHandle[] cases = null;
198
MethodHandles.tableSwitch(simpleTestCase("default"), cases);
199
}
200
201
@Test(expectedExceptions = NullPointerException.class)
202
public void testNullCase() {
203
MethodHandles.tableSwitch(simpleTestCase("default"), simpleTestCase("case"), null);
204
}
205
206
@Test(expectedExceptions = IllegalArgumentException.class,
207
expectedExceptionsMessageRegExp = ".*Not enough cases.*")
208
public void testNotEnoughCases() {
209
MethodHandles.tableSwitch(simpleTestCase("default"));
210
}
211
212
@Test(expectedExceptions = IllegalArgumentException.class,
213
expectedExceptionsMessageRegExp = ".*Case actions must have int as leading parameter.*")
214
public void testNotEnoughParameters() {
215
MethodHandle empty = MethodHandles.empty(MethodType.methodType(void.class));
216
MethodHandles.tableSwitch(empty, empty, empty);
217
}
218
219
@Test(expectedExceptions = IllegalArgumentException.class,
220
expectedExceptionsMessageRegExp = ".*Case actions must have int as leading parameter.*")
221
public void testNoLeadingIntParameter() {
222
MethodHandle empty = MethodHandles.empty(MethodType.methodType(void.class, double.class));
223
MethodHandles.tableSwitch(empty, empty, empty);
224
}
225
226
@Test(expectedExceptions = IllegalArgumentException.class,
227
expectedExceptionsMessageRegExp = ".*Case actions must have the same type.*")
228
public void testWrongCaseType() {
229
// doesn't return a String
230
MethodHandle wrongType = MethodHandles.empty(MethodType.methodType(void.class, int.class));
231
MethodHandles.tableSwitch(simpleTestCase("default"), simpleTestCase("case"), wrongType);
232
}
233
234
}
235
236