Reduces code size for class literal instantiations by using static factory methods. Class and package names are now separately interned again.
Patch by: mmastrac
Review by: me
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1535 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
index 7732c06..82261db 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
@@ -40,6 +40,11 @@
this.dims = dims;
}
+ @Override
+ public String getClassLiteralFactoryMethod() {
+ return "Class.createForArray";
+ }
+
public int getDims() {
return dims;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
index 25f07a6..ba4fd33 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
@@ -15,19 +15,10 @@
*/
package com.google.gwt.dev.jjs.ast;
-import com.google.gwt.dev.jjs.InternalCompilerException;
-
/**
* Java class literal expression.
*/
public class JClassLiteral extends JLiteral {
-
- // Matches constants in our java.lang.Class
- private static final int PRIMITIVE = 0x00000001;
- private static final int INTERFACE = 0x00000002;
- private static final int ARRAY = 0x00000004;
- private static final int ENUM = 0x00000008;
-
private static String getClassName(String fullName) {
int pos = fullName.lastIndexOf(".");
return fullName.substring(pos + 1);
@@ -38,26 +29,7 @@
return fullName.substring(0, pos + 1);
}
- private static JIntLiteral getTypeBitsLit(JProgram program, JType type) {
- int bits;
- if (type instanceof JArrayType) {
- bits = ARRAY;
- } else if (type instanceof JEnumType) {
- bits = ENUM;
- } else if (type instanceof JClassType) {
- bits = 0;
- } else if (type instanceof JInterfaceType) {
- bits = INTERFACE;
- } else if (type instanceof JPrimitiveType) {
- bits = PRIMITIVE;
- } else {
- throw new InternalCompilerException("Unknown kind of type");
- }
- return program.getLiteralInt(bits);
- }
-
- private static JExpression getTypeNameLit(JProgram program, JType type) {
- JExpression typeNameLit;
+ private static String getTypeName(JType type) {
String typeName;
if (type instanceof JArrayType) {
typeName = type.getJsniSignatureName().replace('/', '.');
@@ -65,21 +37,7 @@
typeName = type.getName();
}
- // Split the full class name into package + class so package strings
- // can be merged.
- String className = getClassName(typeName);
- String packageName = getPackageName(typeName);
- if (packageName.length() > 0) {
- // use "com.example.foo." + "Foo"
- typeNameLit = new JBinaryOperation(program, null,
- program.getTypeJavaLangString(), JBinaryOperator.ADD,
- program.getLiteralString(packageName),
- program.getLiteralString(className));
- } else {
- // no package name could be split, just use the full name
- typeNameLit = program.getLiteralString(typeName);
- }
- return typeNameLit;
+ return typeName;
}
private JExpression classObjectAllocation;
@@ -92,15 +50,15 @@
super(program);
refType = type;
- JNewInstance classAlloc = new JNewInstance(program, null,
- program.getTypeJavaLangClass());
- JMethodCall call = new JMethodCall(program, null, classAlloc,
- program.getIndexedMethod("Class.Class"));
+ String typeName = getTypeName(type);
- call.getArgs().add(getTypeNameLit(program, type));
- call.getArgs().add(getTypeBitsLit(program, type));
-
- // TODO: enums
+ JMethod method = program.getIndexedMethod(type.getClassLiteralFactoryMethod());
+ assert method != null;
+
+ JMethodCall call = new JMethodCall(program, null, null,
+ method);
+ call.getArgs().add(program.getLiteralString(getPackageName(typeName)));
+ call.getArgs().add(program.getLiteralString(getClassName(typeName)));
classObjectAllocation = call;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
index 210939f..b023c9a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
@@ -32,6 +32,11 @@
this.isFinal = isFinal;
}
+ @Override
+ public String getClassLiteralFactoryMethod() {
+ return "Class.createForClass";
+ }
+
public boolean isAbstract() {
return isAbstract;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java
index efce503..ee929e4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java
@@ -34,4 +34,8 @@
// TODO: implement traverse?
+ @Override
+ public String getClassLiteralFactoryMethod() {
+ return "Class.createForEnum";
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
index 328b53e..5a7c9da 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
@@ -26,6 +26,11 @@
super(program, info, name);
}
+ @Override
+ public String getClassLiteralFactoryMethod() {
+ return "Class.createForInterface";
+ }
+
public boolean isAbstract() {
return true;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java
index aad4937..bc52521 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java
@@ -15,6 +15,8 @@
*/
package com.google.gwt.dev.jjs.ast;
+import com.google.gwt.dev.jjs.InternalCompilerException;
+
/**
* Java null reference type.
*/
@@ -24,6 +26,11 @@
super(program, null, "<null>");
}
+ @Override
+ public String getClassLiteralFactoryMethod() {
+ throw new InternalCompilerException("Cannot get class literal for null type");
+ }
+
public String getJavahSignatureName() {
return "N";
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
index 30a1c7e..d6e9aef 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
@@ -33,6 +33,11 @@
this.wrapperTypeName = wrapperTypeName;
}
+ @Override
+ public String getClassLiteralFactoryMethod() {
+ return "Class.createForPrimitive";
+ }
+
public String getJavahSignatureName() {
return signatureName;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
index c69cc6f..e6232d7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
@@ -32,6 +32,8 @@
this.defaultValue = defaultValue;
}
+ public abstract String getClassLiteralFactoryMethod();
+
public JLiteral getDefaultValue() {
return defaultValue;
}
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 1e4f83b..b0630aa 100644
--- a/user/super/com/google/gwt/emul/java/lang/Class.java
+++ b/user/super/com/google/gwt/emul/java/lang/Class.java
@@ -28,17 +28,80 @@
private static final int ARRAY = 0x00000004;
private static final int ENUM = 0x00000008;
- private final String typeName;
- private final int modifiers;
+ /**
+ * Create a Class object for an array.
+ *
+ * @skip
+ */
+ static Class<?> createForArray(String packageName, String className) {
+ // Initialize here to avoid method inliner
+ Class<?> clazz = new Class();
+ clazz.typeName = packageName + className;
+ clazz.modifiers = ARRAY;
+ return clazz;
+ }
+
+ /**
+ * Create a Class object for a class.
+ *
+ * @skip
+ */
+ static Class<?> createForClass(String packageName, String className) {
+ // Initialize here to avoid method inliner
+ Class<?> clazz = new Class<Object>();
+ clazz.typeName = packageName + className;
+ return clazz;
+ }
+
+ /**
+ * Create a Class object for an enum.
+ *
+ * @skip
+ */
+ static Class<?> createForEnum(String packageName, String className) {
+ // Initialize here to avoid method inliner
+ Class<?> clazz = new Class<Object>();
+ clazz.typeName = packageName + className;
+ clazz.modifiers = ENUM;
+ return clazz;
+ }
+
+ /**
+ * Create a Class object for an interface.
+ *
+ * @skip
+ */
+ static Class<?> createForInterface(String packageName, String className) {
+ // Initialize here to avoid method inliner
+ Class<?> clazz = new Class<Object>();
+ clazz.typeName = packageName + className;
+ clazz.modifiers = INTERFACE;
+ return clazz;
+ }
+
+ /**
+ * Create a Class object for a primitive.
+ *
+ * @skip
+ */
+ static Class<?> createForPrimitive(String packageName, String className) {
+ // Initialize here to avoid method inliner
+ Class<?> clazz = new Class<Object>();
+ clazz.typeName = packageName + className;
+ clazz.modifiers = PRIMITIVE;
+ return clazz;
+ }
+
+ private int modifiers;
+
+ private String typeName;
/**
* Not publicly instantiable.
*
* @skip
*/
- Class(String typeName, int modifiers) {
- this.typeName = typeName;
- this.modifiers = modifiers;
+ private Class() {
}
public T[] getEnumConstants() {