test/tools/javac/StringsInSwitch/StringSwitches.java

Mon, 02 Nov 2009 21:36:59 -0800

author
darcy
date
Mon, 02 Nov 2009 21:36:59 -0800
changeset 430
8fb9b4be3cb1
child 554
9d9f26857129
permissions
-rw-r--r--

6827009: Project Coin: Strings in Switch
Reviewed-by: jjg, mcimadamore

     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  */
    24 /*
    25  * @test
    26  * @bug 6827009
    27  * @summary Positive tests for strings in switch.
    28  * @author  Joseph D. Darcy
    29  */
    31 public class StringSwitches {
    33     public static void main(String... args) {
    34         int failures = 0;
    36         failures += testPileup();
    37         failures += testSwitchingTwoWays();
    38         failures += testNamedBreak();
    40         if (failures > 0) {
    41             throw new RuntimeException();
    42         }
    43     }
    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;
    57         case "\u0000":
    58             result = 1; break;
    60         case "\u0000\u0000":
    61             return 2;
    63         case "\u0000\u0000\u0000":
    64             result = 3; break;
    66         case "\u0000\u0000\u0000\u0000":
    67             return 4;
    69         case "\u0000\u0000\u0000\u0000\u0000":
    70             result = 5; break;
    72         case "\u0000\u0000\u0000\u0000\u0000\u0000":
    73             return 6;
    75         default:
    76             result = -1;
    77         }
    78         return result;
    79     }
    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         }
    93         if (zeroHashes("foo") != -1) {
    94             failures++;
    95             System.err.println("Failed to get -1 for input string.");
    96         }
    98         return failures;
    99     }
   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;
   109         for(MetaSynVar msv : MetaSynVar.values()) {
   110             int enumResult = enumSwitch(msv);
   111             int stringResult = stringSwitch(msv.name());
   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         }
   121         return failures;
   122     }
   124     private static enum MetaSynVar {
   125         FOO,
   126         BAR,
   127         BAZ,
   128         QUX,
   129         QUUX,
   130         QUUUX,
   131         MUMBLE,
   132         FOOBAR;
   133     }
   135     private static int enumSwitch(MetaSynVar msv) {
   136         int result = 0;
   137         switch(msv) {
   138         case FOO:
   139             result |= (1<<0);
   140             // fallthrough:
   142         case BAR:
   143         case BAZ:
   144             result |= (1<<1);
   145             break;
   147         default:
   148             switch(msv) {
   149             case QUX:
   150                 result |= (1<<2);
   151                 break;
   153             case QUUX:
   154                 result |= (1<<3);
   156             default:
   157                 result |= (1<<4);
   158             }
   159             result |= (1<<5);
   160             break;
   162         case MUMBLE:
   163             result |= (1<<6);
   164             return result;
   166         case FOOBAR:
   167             result |= (1<<7);
   168             break;
   169         }
   170         result |= (1<<8);
   171         return result;
   172     }
   174     private static int stringSwitch(String msvName) {
   175         int result = 0;
   176         switch(msvName) {
   177         case "FOO":
   178             result |= (1<<0);
   179             // fallthrough:
   181         case "BAR":
   182         case "BAZ":
   183             result |= (1<<1);
   184             break;
   186         default:
   187             switch(msvName) {
   188             case "QUX":
   189                 result |= (1<<2);
   190                 break;
   192             case "QUUX":
   193                 result |= (1<<3);
   195             default:
   196                 result |= (1<<4);
   197             }
   198             result |= (1<<5);
   199             break;
   201         case "MUMBLE":
   202             result |= (1<<6);
   203             return result;
   205         case "FOOBAR":
   206             result |= (1<<7);
   207             break;
   208         }
   209         result |= (1<<8);
   210         return result;
   211     }
   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};
   218         for(int i = 0; i < testStrings.length; i++) {
   219             int expected = testExpected[i];
   220             int result = namedBreak(testStrings[i]);
   222             if (result != expected) {
   223                 failures++;
   225                 System.err.printf("On input %s, got %d instead of %d.%n",
   226                                   testStrings[i], result, expected);
   227             }
   228         }
   230         return failures;
   231     }
   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;
   245             case "cc":
   246                 break outer;
   248             default:
   249                 result |= (1<<2);
   250                 return result;
   251             }
   253         case "d":
   254             result |= (1<<3);
   255             break outer;
   257         default:
   258             return result |= (1<<4);
   259         }
   260         result |= (1<<5);
   261         return result;
   262     }
   263 }

mercurial