Fix several @Select issues, adding tests for them:
- @Select only worked if @PluralCount was also on the same message
- @Select for long generated a switch statement which doesn't support
long values
- @Select for booleans generated bad code

Review by: unnurg


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10226 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/i18n/client/Messages.java b/user/src/com/google/gwt/i18n/client/Messages.java
index b0273cf..51f1440 100644
--- a/user/src/com/google/gwt/i18n/client/Messages.java
+++ b/user/src/com/google/gwt/i18n/client/Messages.java
@@ -408,8 +408,8 @@
    * 
    * This annotation is applied to a single parameter of a Messages subinterface
    * and indicates that parameter is to be used to choose the proper form of the
-   * message. The parameter chosen must be of type Enum, String, or a primitive
-   * numeric type.  This is frequently used to get proper gender for
+   * message. The parameter chosen must be of type Enum, String, boolean, or a
+   * primitive integral type.  This is frequently used to get proper gender for
    * translations to languages where surrounding words depend on the gender of
    * a person or noun.  This also marks the parameter as {@link Optional}.
    * 
diff --git a/user/src/com/google/gwt/i18n/rebind/MessagesMethodCreator.java b/user/src/com/google/gwt/i18n/rebind/MessagesMethodCreator.java
index 8e05738..1f5f443 100644
--- a/user/src/com/google/gwt/i18n/rebind/MessagesMethodCreator.java
+++ b/user/src/com/google/gwt/i18n/rebind/MessagesMethodCreator.java
@@ -201,7 +201,9 @@
   private static class GenericSelector extends AlternateFormSelector {
 
     private final JEnumType enumType;
+    private final boolean isBoolean;
     private final boolean isString;
+    private final boolean needsIf;
     private boolean startedIfChain;
 
     /**
@@ -217,13 +219,17 @@
       JPrimitiveType primType = argType.isPrimitive();
       JClassType classType = argType.isClass();
       JEnumType tempEnumType = null;
+      boolean tempIsBoolean = false;
       boolean tempIsString = false;
+      boolean tempNeedsIf = false;
       if (primType != null) {
         if (primType == JPrimitiveType.DOUBLE
             || primType == JPrimitiveType.FLOAT) {
           throw error(logger, m.getName() + ": @Select arguments may only be"
               + " integral primitives, boolean, enums, or String");
         }
+        tempIsBoolean = (primType == JPrimitiveType.BOOLEAN);
+        tempNeedsIf = tempIsBoolean || (primType == JPrimitiveType.LONG);
       } else if (classType != null) {
         tempEnumType = classType.isEnum();
         tempIsString = "java.lang.String".equals(classType.getQualifiedSourceName());
@@ -235,8 +241,11 @@
         throw error(logger, m.getName() + ": @Select arguments may only be"
             + " integral primitives, boolean, enums, or String");
       }
+      tempNeedsIf |= tempIsString;
       enumType = tempEnumType;
+      isBoolean = tempIsBoolean;
       isString = tempIsString;
+      needsIf = tempNeedsIf;
     }
 
     @Override
@@ -271,7 +280,7 @@
     @Override
     public void generateSelectMatchStart(SourceWriter out, TreeLogger logger,
         String value) throws UnableToCompleteException {
-      if (isString) {
+      if (needsIf) {
         if (startedIfChain) {
           out.print("} else ");
         } else {
@@ -280,9 +289,22 @@
         if (AlternateMessageSelector.OTHER_FORM_NAME.equals(value)) {
           out.println("{  // other");
         } else {
-          value = value.replace("\"", "\\\"");
-          out.println("if (\"" + value + "\".equals(arg" + argNumber
-              + ")) {");
+          if (isString) {
+            value = value.replace("\"", "\\\"");
+            out.println("if (\"" + value + "\".equals(arg" + argNumber + ")) {");
+          } else if (isBoolean) {
+            boolean isTrue = Boolean.parseBoolean(value);
+            out.println("if (" + (isTrue ? "" : "!") + "arg" + argNumber + ") {");
+          } else {
+            long longVal;
+            try {
+              longVal = Long.parseLong(value);
+            } catch (NumberFormatException e) {
+              throw error(logger, "'" + value + "' is not a valid long value",
+                  e);
+            }
+            out.println("if (" + longVal + " == arg" + argNumber + ") {");
+          }
         }
       } else {
         if (AlternateMessageSelector.OTHER_FORM_NAME.equals(value)) {
@@ -299,14 +321,14 @@
           }
           out.println("case " + enumConstant.getOrdinal() + ":  // " + value);
         } else {
-          long longVal;
+          int intVal;
           try {
-            longVal = Long.parseLong(value);
+            intVal = Integer.parseInt(value);
           } catch (NumberFormatException e) {
-            throw error(logger, "'" + value + "' is not a valid numeric value",
+            throw error(logger, "'" + value + "' is not a valid integral value",
                 e);
           }
-          out.println("case " + longVal + ":");
+          out.println("case " + intVal + ":");
         }
       }
       out.indent();
@@ -315,7 +337,7 @@
     @Override
     public void generateSelectStart(SourceWriter out, boolean exactMatches) {
       // ignore exactMatches, so "=VALUE" is the same as "VALUE"
-      if (isString) {
+      if (needsIf) {
         startedIfChain = false;
         return;
       }
@@ -1165,7 +1187,7 @@
           null);
     }
     Collection<String> resourceForms = resourceEntry.getForms();
-    if (seenPluralCount) {
+    if (seenPluralCount || seenSelect) {
       paramsAccessor.enablePluralOffsets();
       writer.println(m.getReturnType().getParameterizedQualifiedSourceName()
           + " returnVal = null;");
diff --git a/user/test/com/google/gwt/i18n/client/I18N_en_US_Test.java b/user/test/com/google/gwt/i18n/client/I18N_en_US_Test.java
index 0e96fc3..2966dd6d 100644
--- a/user/test/com/google/gwt/i18n/client/I18N_en_US_Test.java
+++ b/user/test/com/google/gwt/i18n/client/I18N_en_US_Test.java
@@ -35,6 +35,16 @@
     return "com.google.gwt.i18n.I18NTest_en";
   }
 
+  public void testSelect() {
+    TestAnnotatedMessages m = GWT.create(TestAnnotatedMessages.class);
+    assertEquals("#: 14", m.selectBoolean(14, true).asString());
+    assertEquals("Message Count: 14", m.selectBoolean(14, false).asString());
+    assertEquals("Created new order", m.selectInt(0));
+    assertEquals("Updated order 42", m.selectInt(42));
+    assertEquals("Created new order", m.selectLong(0).asString());
+    assertEquals("Updated order 42", m.selectLong(42).asString());
+  }
+
   /**
    * Verifies correct output for multiple, nested selectors, using an enum
    * for gender selection (and SafeHtml output).
diff --git a/user/test/com/google/gwt/i18n/client/TestAnnotatedMessages.java b/user/test/com/google/gwt/i18n/client/TestAnnotatedMessages.java
index 73ca23e..5202197 100644
--- a/user/test/com/google/gwt/i18n/client/TestAnnotatedMessages.java
+++ b/user/test/com/google/gwt/i18n/client/TestAnnotatedMessages.java
@@ -266,6 +266,18 @@
   @AlternateMessage({"one", "A {0}"})
   String twoParamPlural(String name, @PluralCount int count);
 
+  @DefaultMessage("#: {0,number}")
+  @AlternateMessage({"false", "Message Count: {0,number}"})
+  SafeHtml selectBoolean(int count, @Select boolean shortMsg);
+
+  @DefaultMessage("Updated order {0}")
+  @AlternateMessage({"0", "Created new order"})
+  String selectInt(@Select int orderId);
+
+  @DefaultMessage("Updated order {0}")
+  @AlternateMessage({"0", "Created new order"})
+  SafeHtml selectLong(@Select long orderId);
+
   @DefaultMessage("{0} widgets")
   @AlternateMessage({"=0", "No widgets",
       "=1", "A widget",