test/tools/javac/StringsInSwitch/StringSwitches.java

changeset 430
8fb9b4be3cb1
child 554
9d9f26857129
equal deleted inserted replaced
429:c8083dc525b6 430:8fb9b4be3cb1
1 /*
2 * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24 /*
25 * @test
26 * @bug 6827009
27 * @summary Positive tests for strings in switch.
28 * @author Joseph D. Darcy
29 */
30
31 public class StringSwitches {
32
33 public static void main(String... args) {
34 int failures = 0;
35
36 failures += testPileup();
37 failures += testSwitchingTwoWays();
38 failures += testNamedBreak();
39
40 if (failures > 0) {
41 throw new RuntimeException();
42 }
43 }
44
45 /*
46 * A zero length string and all strings consisting only of the
47 * zero character \u0000 have a hash code of zero. This method
48 * maps such strings to the number of times \u0000 appears for 0
49 * through 6 occurrences.
50 */
51 private static int zeroHashes(String s) {
52 int result = Integer.MAX_VALUE;
53 switch(s) {
54 case "":
55 return 0;
56
57 case "\u0000":
58 result = 1; break;
59
60 case "\u0000\u0000":
61 return 2;
62
63 case "\u0000\u0000\u0000":
64 result = 3; break;
65
66 case "\u0000\u0000\u0000\u0000":
67 return 4;
68
69 case "\u0000\u0000\u0000\u0000\u0000":
70 result = 5; break;
71
72 case "\u0000\u0000\u0000\u0000\u0000\u0000":
73 return 6;
74
75 default:
76 result = -1;
77 }
78 return result;
79 }
80
81 private static int testPileup() {
82 int failures = 0;
83 String zero = "";
84 for(int i = 0; i <= 6; i++, zero += "\u0000") {
85 int result = zeroHashes(zero);
86 if (result != i) {
87 failures++;
88 System.err.printf("For string \"%s\" unexpectedly got %d instead of %d%n.",
89 zero, result, i);
90 }
91 }
92
93 if (zeroHashes("foo") != -1) {
94 failures++;
95 System.err.println("Failed to get -1 for input string.");
96 }
97
98 return failures;
99 }
100
101 /**
102 * Verify that a switch on an enum and a switch with the same
103 * structure on the string name of an enum compute equivalent
104 * values.
105 */
106 private static int testSwitchingTwoWays() {
107 int failures = 0;
108
109 for(MetaSynVar msv : MetaSynVar.values()) {
110 int enumResult = enumSwitch(msv);
111 int stringResult = stringSwitch(msv.name());
112
113 if (enumResult != stringResult) {
114 failures++;
115 System.err.printf("One value %s, computed 0x%x with the enum switch " +
116 "and 0x%x with the string one.%n",
117 msv, enumResult, stringResult);
118 }
119 }
120
121 return failures;
122 }
123
124 private static enum MetaSynVar {
125 FOO,
126 BAR,
127 BAZ,
128 QUX,
129 QUUX,
130 QUUUX,
131 MUMBLE,
132 FOOBAR;
133 }
134
135 private static int enumSwitch(MetaSynVar msv) {
136 int result = 0;
137 switch(msv) {
138 case FOO:
139 result |= (1<<0);
140 // fallthrough:
141
142 case BAR:
143 case BAZ:
144 result |= (1<<1);
145 break;
146
147 default:
148 switch(msv) {
149 case QUX:
150 result |= (1<<2);
151 break;
152
153 case QUUX:
154 result |= (1<<3);
155
156 default:
157 result |= (1<<4);
158 }
159 result |= (1<<5);
160 break;
161
162 case MUMBLE:
163 result |= (1<<6);
164 return result;
165
166 case FOOBAR:
167 result |= (1<<7);
168 break;
169 }
170 result |= (1<<8);
171 return result;
172 }
173
174 private static int stringSwitch(String msvName) {
175 int result = 0;
176 switch(msvName) {
177 case "FOO":
178 result |= (1<<0);
179 // fallthrough:
180
181 case "BAR":
182 case "BAZ":
183 result |= (1<<1);
184 break;
185
186 default:
187 switch(msvName) {
188 case "QUX":
189 result |= (1<<2);
190 break;
191
192 case "QUUX":
193 result |= (1<<3);
194
195 default:
196 result |= (1<<4);
197 }
198 result |= (1<<5);
199 break;
200
201 case "MUMBLE":
202 result |= (1<<6);
203 return result;
204
205 case "FOOBAR":
206 result |= (1<<7);
207 break;
208 }
209 result |= (1<<8);
210 return result;
211 }
212
213 private static int testNamedBreak() {
214 int failures = 0;
215 String[] testStrings = {"a", "b", "c", "d", "e"};
216 int[] testExpected = { 0b101011, 0b101, 0b100001, 0b101000, 0b10000};
217
218 for(int i = 0; i < testStrings.length; i++) {
219 int expected = testExpected[i];
220 int result = namedBreak(testStrings[i]);
221
222 if (result != expected) {
223 failures++;
224
225 System.err.printf("On input %s, got %d instead of %d.%n",
226 testStrings[i], result, expected);
227 }
228 }
229
230 return failures;
231 }
232
233 private static int namedBreak(String s) {
234 int result = 0;
235 outer: switch(s) {
236 case "a":
237 case "b":
238 case "c":
239 result |= (1<<0);
240 inner: switch(s + s) {
241 case "aa":
242 result |= (1<<1);
243 break inner;
244
245 case "cc":
246 break outer;
247
248 default:
249 result |= (1<<2);
250 return result;
251 }
252
253 case "d":
254 result |= (1<<3);
255 break outer;
256
257 default:
258 return result |= (1<<4);
259 }
260 result |= (1<<5);
261 return result;
262 }
263 }

mercurial