Added support for Class.getCanonicalName() to JRE emulation.

Change-Id: Ie3965cde15bfa68f57195e814c9cd6ffb7afb8a2
diff --git a/user/super/com/google/gwt/emul/java/lang/Class.java b/user/super/com/google/gwt/emul/java/lang/Class.java
index 5b52b34..92a340d 100644
--- a/user/super/com/google/gwt/emul/java/lang/Class.java
+++ b/user/super/com/google/gwt/emul/java/lang/Class.java
@@ -57,12 +57,15 @@
       if (this.isPrimitive()) {
         // Primitives have an additional prepended space.
         clazz.typeName = this.simpleName.substring(1);
+        clazz.canonicalName = clazz.typeName;
       } else {
         clazz.typeName = "L" + this.typeName;
+        clazz.canonicalName = this.typeName.replace('$', '.');
       }
       clazz.simpleName = this.simpleName;
       for (int i = 0; i < dimensions; i++) {
         clazz.typeName = "[" + clazz.typeName;
+        clazz.canonicalName += "[]";
         clazz.simpleName += "[]";
       }
       if (!this.isPrimitive()) {
@@ -147,6 +150,7 @@
     Class<?> clazz = new Class<Object>();
     if (clazz.isClassMetadataEnabled()) {
       clazz.typeName = className;
+      clazz.canonicalName = className;
       clazz.simpleName = primitiveTypeId;
     } else {
       synthesizePrimitiveNamesFromTypeId(clazz, primitiveTypeId);
@@ -224,6 +228,11 @@
   private static native void initializeNames(Class<?> clazz, String packageName,
       String className) /*-{
     clazz.@java.lang.Class::typeName = packageName + className;
+    if (className.indexOf("$") == -1) {
+      clazz.@java.lang.Class::canonicalName = clazz.@java.lang.Class::typeName;
+    } else {
+      clazz.@java.lang.Class::canonicalName = packageName + className.replace("$", ".");
+    }
     clazz.@java.lang.Class::simpleName = className;
   }-*/;
 
@@ -241,6 +250,7 @@
 
     clazz.@java.lang.Class::typeName = "Class$" +
         (!!typeId ? "S" + typeId : "" + clazz.@java.lang.Class::sequentialId);
+    clazz.@java.lang.Class::canonicalName = clazz.@java.lang.Class::typeName;
     clazz.@java.lang.Class::simpleName = clazz.@java.lang.Class::typeName;
   }-*/;
 
@@ -251,6 +261,7 @@
    */
   static native void synthesizePrimitiveNamesFromTypeId(Class<?> clazz, String primitiveTypeId) /*-{
     clazz.@java.lang.Class::typeName = "Class$" + primitiveTypeId;
+    clazz.@java.lang.Class::canonicalName = clazz.@java.lang.Class::typeName;
     clazz.@java.lang.Class::simpleName = clazz.@java.lang.Class::typeName;
   }-*/;
 
@@ -271,6 +282,8 @@
 
   private String typeName;
 
+  private String canonicalName;
+
   private JavaScriptObject typeId;
 
   private JavaScriptObject arrayLiterals;
@@ -295,6 +308,10 @@
     return false;
   }
 
+  public String getCanonicalName() {
+    return canonicalName;
+  }
+
   public Class<?> getComponentType() {
     return componentType;
   }
diff --git a/user/test/com/google/gwt/dev/jjs/test/ClassObjectTest.java b/user/test/com/google/gwt/dev/jjs/test/ClassObjectTest.java
index ca6add1..d5007f1 100644
--- a/user/test/com/google/gwt/dev/jjs/test/ClassObjectTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/ClassObjectTest.java
@@ -57,9 +57,12 @@
       assertEquals(Object.class, o.getClass().getSuperclass());
       assertEquals("[Lcom.google.gwt.dev.jjs.test.ClassObjectTest$Foo;",
           o.getClass().getName());
+      assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest.Foo[]",
+          o.getClass().getCanonicalName());
       assertEquals("class [Lcom.google.gwt.dev.jjs.test.ClassObjectTest$Foo;",
           o.getClass().toString());
     }
+
     assertTrue(o.getClass().isArray());
     assertFalse(o.getClass().isEnum());
     assertFalse(o.getClass().isInterface());
@@ -88,6 +91,8 @@
       assertEquals(Object.class, o.getClass().getSuperclass());
       assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest$Foo",
           Foo.class.getName());
+      assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest.Foo",
+          Foo.class.getCanonicalName());
       assertEquals("class com.google.gwt.dev.jjs.test.ClassObjectTest$Foo",
           Foo.class.toString());
     }
@@ -103,6 +108,8 @@
     if (expectClassMetadata()) {
       assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest$Bar",
           getBarClass().getName());
+      assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest.Bar",
+          getBarClass().getCanonicalName());
     }
   }
 
@@ -113,6 +120,8 @@
       assertEquals(Enum.class, o.getClass().getSuperclass());
       assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest$Bar",
           o.getClass().getName());
+      assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest.Bar",
+          o.getClass().getCanonicalName());
       assertEquals("class com.google.gwt.dev.jjs.test.ClassObjectTest$Bar",
           o.getClass().toString());
     }
@@ -147,6 +156,8 @@
     if (expectClassMetadata()) {
       assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest$IFoo",
           IFoo.class.getName());
+      assertEquals("com.google.gwt.dev.jjs.test.ClassObjectTest.IFoo",
+          IFoo.class.getCanonicalName());
       assertEquals(
           "interface com.google.gwt.dev.jjs.test.ClassObjectTest$IFoo",
           IFoo.class.toString());
@@ -162,6 +173,7 @@
     assertNull(int.class.getSuperclass());
     if (expectClassMetadata()) {
       assertEquals("int", int.class.getName());
+      assertEquals("int", int.class.getCanonicalName());
       assertEquals("int", int.class.toString());
     }
     assertFalse(int.class.isArray());