Reduces class and JSNI loading for RPC in devmode.
- Makes GwtScriptOnly work with JSNI methods.
- Modifies the RPC generator to tag native methods with GwtScriptOnly.
- Modifies the RPC generator to defer class loads of FieldSerializers until needed.
Review at http://gwt-code-reviews.appspot.com/1215801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9424 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
index fc333f6..9572448 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
@@ -15,10 +15,12 @@
*/
package com.google.gwt.dev.javac;
+import com.google.gwt.core.client.GwtScriptOnly;
import com.google.gwt.core.ext.TreeLogger.HelpInfo;
import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.SourceOrigin;
+import com.google.gwt.dev.jjs.ast.JAnnotation;
import com.google.gwt.dev.js.JsParser;
import com.google.gwt.dev.js.JsParserException;
import com.google.gwt.dev.js.JsParserException.SourceDetail;
@@ -30,12 +32,15 @@
import com.google.gwt.dev.util.collect.IdentityHashMap;
import com.google.gwt.dev.util.collect.IdentityMaps;
+import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.Util;
@@ -66,10 +71,12 @@
private static final class JsniMethodImpl extends JsniMethod {
private final JsFunction func;
private final String name;
+ private boolean isScriptOnly;
- public JsniMethodImpl(String name, JsFunction func) {
+ public JsniMethodImpl(String name, JsFunction func, boolean isScriptOnly) {
this.name = name;
this.func = func;
+ this.isScriptOnly = isScriptOnly;
}
@Override
@@ -78,6 +85,11 @@
}
@Override
+ public boolean isScriptOnly() {
+ return isScriptOnly;
+ }
+
+ @Override
public int line() {
return func.getSourceInfo().getStartLine();
}
@@ -114,6 +126,20 @@
}
private static class Visitor extends MethodVisitor {
+ private static boolean isScriptOnly(AbstractMethodDeclaration method) {
+ if (method.annotations == null) {
+ return false;
+ }
+ for (Annotation a : method.annotations) {
+ JAnnotation annotation;
+ ReferenceBinding binding = (ReferenceBinding) a.resolvedType;
+ String name = CharOperation.toString(binding.compoundName);
+ if (name.equals(GwtScriptOnly.class.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
private final Map<AbstractMethodDeclaration, JsniMethod> jsniMethods;
private final JsProgram jsProgram;
@@ -140,7 +166,7 @@
if (jsFunction != null) {
String jsniSignature = getJsniSignature(enclosingType, method);
jsniMethods.put(method, new JsniMethodImpl(jsniSignature,
- jsFunction));
+ jsFunction, isScriptOnly(method)));
}
}
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java b/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java
index e00d001..fd0c87b 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java
@@ -29,6 +29,12 @@
public abstract JsFunction function();
/**
+ * Returns true if this JSNI function should only be used from script.
+ * See {@link com.google.gwt.core.client.GwtScriptOnly GwtScriptOnly}.
+ */
+ public abstract boolean isScriptOnly();
+
+ /**
* Starting line number of the method.
*/
public abstract int line();
@@ -49,7 +55,7 @@
public abstract String[] paramNames();
/**
- * Gets the JsProgram in which {@link #function(TreeLogger)} is located.
+ * Gets the JsProgram in which this method is located.
*/
public abstract JsProgram program();
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
index 8acc0f9..d46c927 100644
--- a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
+++ b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
@@ -226,6 +226,33 @@
private static DiskCache diskCache = new DiskCache();
+ private static final Map<String,CompilerEventType> eventsByGeneratorType = new HashMap<String,CompilerEventType>();
+ static {
+ eventsByGeneratorType.put(
+ "com.google.gwt.resources.rebind.context.InlineClientBundleGenerator",
+ CompilerEventType.GENERATOR_CLIENT_BUNDLE);
+ eventsByGeneratorType.put("com.google.gwt.i18n.rebind.LocalizableGenerator",
+ CompilerEventType.GENERATOR_I18N);
+ eventsByGeneratorType.put("com.google.gwt.i18n.rebind.LocaleInfoGenerator",
+ CompilerEventType.GENERATOR_I18N);
+ eventsByGeneratorType.put(
+ "com.google.gwt.i18n.rebind.CurrencyListGenerator",
+ CompilerEventType.GENERATOR_I18N);
+ eventsByGeneratorType.put(
+ "com.google.gwt.i18n.rebind.CustomDateTimeFormatGenerator",
+ CompilerEventType.GENERATOR_I18N);
+ eventsByGeneratorType.put(
+ "com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator",
+ CompilerEventType.GENERATOR_RPC);
+ eventsByGeneratorType.put("com.google.gwt.rpc.rebind.RpcServiceGenerator",
+ CompilerEventType.GENERATOR_RPC); // deRPC
+ eventsByGeneratorType.put(
+ "com.google.gwt.uibinder.rebind.UiBinderGenerator",
+ CompilerEventType.GENERATOR_UIBINDER);
+ eventsByGeneratorType.put("com.google.gwt.inject.rebind.GinjectorGenerator",
+ CompilerEventType.GENERATOR_GIN);
+ }
+
private final ArtifactSet allGeneratedArtifacts;
private final Set<GeneratedUnit> committedGeneratedCups = new HashSet<GeneratedUnit>();
@@ -421,8 +448,16 @@
setCurrentGenerator(generatorClass);
long before = System.currentTimeMillis();
- Event generatorEvent = SpeedTracerLogger.start(CompilerEventType.GENERATOR, "class",
- generator.getClass().getName(), "type", typeName);
+ String generatorClassName = generator.getClass().getName();
+ CompilerEventType type = eventsByGeneratorType.get(generatorClassName);
+
+ if (type == null) {
+ type = CompilerEventType.GENERATOR_OTHER;
+ }
+
+ Event generatorEvent = SpeedTracerLogger.start(type, "class",
+ generatorClassName, "type", typeName);
+
try {
String className = generator.generate(logger, this, typeName);
long after = System.currentTimeMillis();
diff --git a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
index 06a83fd..bfd2454 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -42,6 +42,9 @@
import com.google.gwt.dev.util.Name.SourceOrBinaryName;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.collect.Lists;
+import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.util.tools.Utility;
import org.apache.commons.collections.map.AbstractReferenceMap;
@@ -1247,7 +1250,14 @@
if (unit == null || unit.getJsniMethods() == null) {
return;
}
- shellJavaScriptHost.createNativeMethods(logger, unit.getJsniMethods(), this);
+ Event event = SpeedTracerLogger.start(DevModeEventType.LOAD_JSNI, "unit",
+ unit.getTypeName());
+ try {
+ shellJavaScriptHost.createNativeMethods(logger, unit.getJsniMethods(),
+ this);
+ } finally {
+ event.end();
+ }
}
private void maybeInitializeScriptOnlyClassLoader() {
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
index 7d4f75a..97b2f05 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
@@ -46,6 +46,9 @@
}
StringBuilder jsni = new StringBuilder();
for (JsniMethod jsniMethod : jsniMethods) {
+ if (jsniMethod.isScriptOnly()) {
+ continue;
+ }
String body = Jsni.getJavaScriptForHostedMode(logger, dispatchIdOracle,
jsniMethod);
if (body == null) {
diff --git a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
index e5950a7..9d3d4a3 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
@@ -27,7 +27,15 @@
COMPILE_PERMUTATIONS("CompilePermutations", "BurlyWood"), //
JJS_COMPILE_PERMUTATION("JjsCompilePermutation", "Moccasin"), //
DRAFT_OPTIMIZE("DraftOptimizer", "Blue"), //
- GENERATOR("Generator", "Red"), //
+ GENERATOR_CLIENT_BUNDLE("Generator ClientBundle", "#CCCC33"), //
+ GENERATOR_I18N("Generator I18N", "#FF00CC"), //
+ GENERATOR_RPC("Generator RPC", "#3300CC"), //
+ GENERATOR_RPC_STOB("Generator RPC STOB", "#3300CC"), //
+ GENERATOR_RPC_TYPE_SERIALIZER("Generator RPC Type Serializer", "#3300CC"), //
+ GENERATOR_RPC_FIELD_SERIALIZER("Generator RPC Field Serializer", "#3300CC"), //
+ GENERATOR_UIBINDER("Generator UiBinder", "#FFFF00"), //
+ GENERATOR_GIN("Generator GIN", "#009900"), //
+ GENERATOR_OTHER("Generator (Other)", "Red"), //
JDT_COMPILER("JdtCompiler1", "#6c6"), //
JDT_COMPILER2("JdtCompiler2", "#0c0"), //
JDT_COMPILER3("JdtCompiler3", "#494"), //
diff --git a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/DevModeEventType.java b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/DevModeEventType.java
index cb4b380..c011fe9 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/DevModeEventType.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/DevModeEventType.java
@@ -30,6 +30,7 @@
JAVA_TO_JS_CALL("Java to JS call", "LightSkyBlue"), //
JETTY_STARTUP("Jetty startup", "Orchid"), //
JS_TO_JAVA_CALL("JS to Java call", "Orange"), //
+ LOAD_JSNI("Parse and Load JSNI", "LightCoral"), //
MODULE_INIT("Module init", "Khaki"), //
MODULE_SPACE_CLASS_LOAD("ModuleSpace class load", "MintCream"), //
MODULE_SPACE_HOST_CREATE("ModuleSpaceHost create", "Peachpuff"), //
diff --git a/dev/core/super/com/google/gwt/core/client/GwtScriptOnly.java b/dev/core/super/com/google/gwt/core/client/GwtScriptOnly.java
index 9161f97..811baed 100644
--- a/dev/core/super/com/google/gwt/core/client/GwtScriptOnly.java
+++ b/dev/core/super/com/google/gwt/core/client/GwtScriptOnly.java
@@ -29,8 +29,13 @@
* to provide web-mode implementations of (binary-only) types that the developer
* wishes to use in hosted mode. This can be used, for instance, to provide a
* reference implementation to develop unit tests.
+ * <p>
+ * This annotation may also be applied to jsni methods to prevent them from
+ * being parsed and loaded for devmode. This is done under certain
+ * circumstances as an optimization to avoid loading very large jsni methods
+ * which are only executed in webmode.
*/
@Documented
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.METHOD})
public @interface GwtScriptOnly {
}
diff --git a/tools/api-checker/config/gwt21_22userApi.conf b/tools/api-checker/config/gwt21_22userApi.conf
index 37f4e11..63bdabe 100644
--- a/tools/api-checker/config/gwt21_22userApi.conf
+++ b/tools/api-checker/config/gwt21_22userApi.conf
@@ -48,7 +48,8 @@
:com/google/gwt/rpc/client/impl/EscapeUtil.java\
:com/google/gwt/soyc/**\
:com/google/gwt/safehtml/shared/SafeHtmlHostedModeUtils.java\
-:com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java\
+:com/google/gwt/user/client/rpc/core/**\
+:com/google/gwt/user/client/rpc/impl/**\
:com/google/gwt/uibinder/attributeparsers/**\
:com/google/gwt/uibinder/elementparsers/**\
:com/google/gwt/uibinder/testing/**\
@@ -90,7 +91,8 @@
:user/src/com/google/gwt/rpc/client/impl/ClientWriterFactory.java\
:user/src/com/google/gwt/rpc/client/impl/EscapeUtil.java\
:user/src/com/google/gwt/safehtml/shared/SafeHtmlHostedModeUtils.java\
-:user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java\
+:user/src/com/google/gwt/user/client/rpc/core/**\
+:user/src/com/google/gwt/user/client/rpc/impl/**\
:user/src/com/google/gwt/uibinder/attributeparsers/**\
:user/src/com/google/gwt/uibinder/elementparsers/**\
:user/src/com/google/gwt/uibinder/testing/**\
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
index 121ab51..b27afae 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
@@ -32,8 +32,8 @@
*/
public static final class ArrayList_CustomFieldSerializer {
- public static Class<?> concreteType() {
- return java.util.Arrays.asList().getClass();
+ public static String concreteType() {
+ return java.util.Arrays.asList().getClass().getName();
}
/*
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
index 225bf3b..6b54997 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
@@ -33,8 +33,8 @@
*/
public static final class EmptyList_CustomFieldSerializer {
- public static Class<?> concreteType() {
- return java.util.Collections.emptyList().getClass();
+ public static String concreteType() {
+ return java.util.Collections.emptyList().getClass().getName();
}
@SuppressWarnings({"unused", "unchecked"})
@@ -61,8 +61,8 @@
*/
public static final class EmptyMap_CustomFieldSerializer {
- public static Class<?> concreteType() {
- return java.util.Collections.emptyMap().getClass();
+ public static String concreteType() {
+ return java.util.Collections.emptyMap().getClass().getName();
}
@SuppressWarnings({"unused", "unchecked"})
@@ -89,8 +89,8 @@
*/
public static final class EmptySet_CustomFieldSerializer {
- public static Class<?> concreteType() {
- return java.util.Collections.emptySet().getClass();
+ public static String concreteType() {
+ return java.util.Collections.emptySet().getClass().getName();
}
@SuppressWarnings({"unused", "unchecked"})
@@ -117,8 +117,8 @@
*/
public static final class SingletonList_CustomFieldSerializer {
- public static Class<?> concreteType() {
- return java.util.Collections.singletonList(null).getClass();
+ public static String concreteType() {
+ return java.util.Collections.singletonList(null).getClass().getName();
}
@SuppressWarnings({"unused", "unchecked"})
diff --git a/user/src/com/google/gwt/user/client/rpc/impl/ReflectionHelper.java b/user/src/com/google/gwt/user/client/rpc/impl/ReflectionHelper.java
new file mode 100644
index 0000000..924abf6
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/rpc/impl/ReflectionHelper.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.rpc.impl;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Provides access to reflection capability, but only when running from
+ * bytecode.
+ */
+public class ReflectionHelper {
+
+ /**
+ * Loads {@code klass} using Class.forName.
+ */
+ public static Class<?> loadClass(String klass) throws Exception {
+ return Class.forName(klass);
+ }
+
+ /**
+ * Creates a new instance of {@code klass}. The class must have a no-arg
+ * constructor. The constructor may have any access modifier (for example,
+ * private).
+ */
+ public static <T> T newInstance(Class<T> klass)
+ throws Exception {
+ Constructor<T> c = klass.getDeclaredConstructor();
+ c.setAccessible(true);
+ return c.newInstance();
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/rpc/impl/SerializerBase.java b/user/src/com/google/gwt/user/client/rpc/impl/SerializerBase.java
index 79132e5..652e399 100644
--- a/user/src/com/google/gwt/user/client/rpc/impl/SerializerBase.java
+++ b/user/src/com/google/gwt/user/client/rpc/impl/SerializerBase.java
@@ -23,6 +23,7 @@
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -64,17 +65,20 @@
}-*/;
}
- private final Map<String, TypeHandler> methodMapJava;
-
+ private final Map<String, TypeHandler> handlerCache;
+
+ private final Map<String, String> methodMapJava;
+
private final MethodMap methodMapNative;
- private final Map<Class<?>, String> signatureMapJava;
+ private final Map<String, String> signatureMapJava;
private final JsArrayString signatureMapNative;
- public SerializerBase(Map<String, TypeHandler> methodMapJava,
- MethodMap methodMapNative, Map<Class<?>, String> signatureMapJava,
+ public SerializerBase(Map<String, String> methodMapJava,
+ MethodMap methodMapNative, Map<String, String> signatureMapJava,
JsArrayString signatureMapNative) {
+ this.handlerCache = new HashMap<String, TypeHandler>();
this.methodMapJava = methodMapJava;
this.methodMapNative = methodMapNative;
this.signatureMapJava = signatureMapJava;
@@ -97,7 +101,7 @@
if (GWT.isScript()) {
return signatureMapNative.get(clazz.hashCode());
} else {
- return signatureMapJava.get(clazz);
+ return signatureMapJava.get(clazz.getName());
}
}
@@ -139,14 +143,27 @@
private TypeHandler getTypeHandler(String typeSignature)
throws SerializationException {
- TypeHandler typeHandler = methodMapJava.get(typeSignature);
- if (typeHandler == null) {
- /*
- * Probably trying to serialize a type that isn't supposed to be
- * serializable.
- */
+ String typeHandlerClass = methodMapJava.get(typeSignature);
+
+ if (typeHandlerClass == null) {
+ /*
+ * Probably trying to serialize a type that isn't supposed to be
+ * serializable.
+ */
throw new SerializationException(typeSignature);
}
+
+ TypeHandler typeHandler = handlerCache.get(typeHandlerClass);
+
+ if (typeHandler == null) {
+ try {
+ Class<?> klass = ReflectionHelper.loadClass(typeHandlerClass);
+ typeHandler = (TypeHandler) ReflectionHelper.newInstance(klass);
+ handlerCache.put(typeHandlerClass, typeHandler);
+ } catch (Exception e) {
+ throw new SerializationException(e);
+ }
+ }
return typeHandler;
}
}
diff --git a/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java b/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java
index f4c81df..b22d071 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java
@@ -35,7 +35,7 @@
private static final String NO_INSTANTIATE_METHOD = "Custom Field Serializer ''{0}'' does not define an instantiate method: ''public static {1} instantiate({2} reader)''; but ''{1}'' is not default instantiable";
private static final String NO_SERIALIZE_METHOD = "Custom Field Serializer ''{0}'' does not define a serialize method: ''public static void serialize({1} writer,{2} instance)''";
private static final String TOO_MANY_METHODS = "Custom Field Serializer ''{0}'' defines too many methods named ''{1}''; please define only one method with that name";
- private static final String WRONG_CONCRETE_TYPE_RETURN = "Custom Field Serializer ''{0}'' returns the wrong type from ''concreteType''; return type must be ''java.lang.Class''";
+ private static final String WRONG_CONCRETE_TYPE_RETURN = "Custom Field Serializer ''{0}'' returns the wrong type from ''concreteType''; return type must be ''java.lang.String''";
public static JMethod getConcreteTypeMethod(JClassType serializer) {
return serializer.findMethod("concreteType", new JType[0]);
@@ -163,7 +163,7 @@
JMethod concreteTypeMethod = getConcreteTypeMethod(serializer);
if (concreteTypeMethod != null) {
- if (!"java.lang.Class".equals(concreteTypeMethod.getReturnType().getQualifiedSourceName())) {
+ if (!"java.lang.String".equals(concreteTypeMethod.getReturnType().getQualifiedSourceName())) {
// Wrong return type.
reasons.add(MessageFormat.format(WRONG_CONCRETE_TYPE_RETURN,
serializer.getQualifiedSourceName()));
diff --git a/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java b/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
index dab6529..a8102ba 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
@@ -112,8 +112,6 @@
writeFieldAccessors();
- writeConcreteTypeMethod();
-
writeDeserializeMethod();
maybeWriteInstatiateMethod();
@@ -579,37 +577,6 @@
}
}
- /**
- * Writes the concreteType method, for loading a Java Class -> TypeHandler
- * map.
- *
- * <pre>
- * public static Class<?> concreteType() {
- * return com.google.gwt.sample.client.Student.class;
- * }
- * </pre>
- */
- private void writeConcreteTypeMethod() {
- if (customFieldSerializer != null
- && CustomFieldSerializerValidator.getConcreteTypeMethod(customFieldSerializer) != null) {
- return;
- }
-
- if (classIsAccessible()) {
- sourceWriter.println("public static Class<?> concreteType() {");
- sourceWriter.indentln("return "
- + serializableClass.getQualifiedSourceName() + ".class;");
- sourceWriter.println("}");
- sourceWriter.println();
- } else {
- String jsniTypeRef = SerializationUtils.getRpcTypeName(serializableClass);
- sourceWriter.println("public static native Class<?> concreteType() /*-{");
- sourceWriter.indentln("return @" + jsniTypeRef + "::class;");
- sourceWriter.println("}-*/;");
- sourceWriter.println();
- }
- }
-
private void writeDeserializeMethod() {
if (customFieldSerializer != null) {
return;
diff --git a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
index e554f1d..4921dd4 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
@@ -37,6 +37,9 @@
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.generator.NameFactory;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
@@ -280,6 +283,8 @@
propertyOracle);
// Determine the set of serializable types
+ Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_STOB);
+
SerializableTypeOracleBuilder typesSentFromBrowserBuilder = new SerializableTypeOracleBuilder(
logger, propertyOracle, typeOracle);
typesSentFromBrowserBuilder.setTypeFilter(blacklistTypeFilter);
@@ -328,7 +333,8 @@
writer.close();
rpcLog = stringWriter.toString();
}
-
+ event.end();
+
generateTypeHandlers(logger, context, typesSentFromBrowser,
typesSentToBrowser);
@@ -687,11 +693,13 @@
GeneratorContext context, SerializableTypeOracle typesSentFromBrowser,
SerializableTypeOracle typesSentToBrowser)
throws UnableToCompleteException {
+ Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_TYPE_SERIALIZER);
TypeSerializerCreator tsc = new TypeSerializerCreator(logger,
typesSentFromBrowser, typesSentToBrowser, context,
SerializationUtils.getTypeSerializerQualifiedName(serviceIntf),
SerializationUtils.getTypeSerializerSimpleName(serviceIntf));
tsc.realize(logger);
+ event.end();
typeStrings = new HashMap<JType, String>(tsc.getTypeStrings());
typeStrings.put(serviceIntf, TypeNameObfuscator.SERVICE_INTERFACE_ID);
diff --git a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
index f391d2c..9c0101a 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
@@ -17,6 +17,7 @@
package com.google.gwt.user.rebind.rpc;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.GwtScriptOnly;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.ConfigurationProperty;
@@ -28,6 +29,9 @@
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
import com.google.gwt.user.client.rpc.impl.SerializerBase;
@@ -205,6 +209,7 @@
*/
private void createFieldSerializer(TreeLogger logger, GeneratorContext ctx,
JType type) {
+ Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_FIELD_SERIALIZER);
assert (type != null);
assert (serializationOracle.isSerializable(type) || deserializationOracle.isSerializable(type));
@@ -228,6 +233,7 @@
serializationOracle, deserializationOracle, (JClassType) type,
customFieldSerializer);
creator.realize(logger, ctx);
+ event.end();
}
/*
@@ -276,6 +282,7 @@
composerFactory.addImport(TypeHandler.class.getName());
composerFactory.addImport(HashMap.class.getName());
composerFactory.addImport(Map.class.getName());
+ composerFactory.addImport(GwtScriptOnly.class.getName());
composerFactory.setSuperclass(SerializerBase.class.getName());
return composerFactory.createSourceWriter(ctx, printWriter);
@@ -317,15 +324,15 @@
}
/**
- * Writes a method to produce a map of type string -> {@link TypeHandler}
- * for Java.
+ * Writes a method to produce a map of type string -> class name of
+ * {@link TypeHandler} for Java.
*
* <pre>
- * private static Map<String, TypeHandler> loadMethodsJava() {
- * Map<String, TypeHandler> result = new HashMap<String, TypeHandler>();
+ * private static Map<String, String> loadMethodsJava() {
+ * Map<String, String> result = new HashMap<String, String>();
* result.put(
* "java.lang.String/2004016611",
- * new com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.Handler());
+ * "com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer"
* ...
* return result;
* }
@@ -333,9 +340,9 @@
*/
private void writeLoadMethodsJava() {
srcWriter.println("@SuppressWarnings(\"deprecation\")");
- srcWriter.println("private static Map<String, TypeHandler> loadMethodsJava() {");
+ srcWriter.println("private static Map<String, String> loadMethodsJava() {");
srcWriter.indent();
- srcWriter.println("Map<String, TypeHandler> result = new HashMap<String, TypeHandler>();");
+ srcWriter.println("Map<String, String> result = new HashMap<String, String>();");
List<JType> filteredTypes = new ArrayList<JType>();
JType[] types = getSerializableTypes();
@@ -352,9 +359,9 @@
String typeString = typeStrings.get(type);
assert typeString != null : "Missing type signature for "
+ type.getQualifiedSourceName();
- srcWriter.println("result.put(\"" + typeString + "\", new "
+ srcWriter.println("result.put(\"" + typeString + "\", \""
+ SerializationUtils.getStandardSerializerName((JClassType) type)
- + "());");
+ + "\");");
}
srcWriter.println("return result;");
@@ -381,6 +388,7 @@
*/
private void writeLoadMethodsNative() {
srcWriter.println("@SuppressWarnings(\"deprecation\")");
+ srcWriter.println("@GwtScriptOnly");
srcWriter.println("private static native MethodMap loadMethodsNative() /*-{");
srcWriter.indent();
srcWriter.println("var result = {};");
@@ -433,11 +441,11 @@
}
/**
- * Writes a method to produce a map of class to type string for Java.
+ * Writes a method to produce a map of class name to type string for Java.
*
* <pre>
- * private static Map<Class<?>, String> loadSignaturesJava() {
- * Map<Class<?>, String> result = new HashMap<Class<?>, String>();
+ * private static Map<String<?>, String> loadSignaturesJava() {
+ * Map<String<?>, String> result = new HashMap<String<?>, String>();
* result.put(
* com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.concreteType(),
* "java.lang.String/2004016611");
@@ -448,9 +456,9 @@
*/
private void writeLoadSignaturesJava() {
srcWriter.println("@SuppressWarnings(\"deprecation\")");
- srcWriter.println("private static Map<Class<?>, String> loadSignaturesJava() {");
+ srcWriter.println("private static Map<String, String> loadSignaturesJava() {");
srcWriter.indent();
- srcWriter.println("Map<Class<?>, String> result = new HashMap<Class<?>, String>();");
+ srcWriter.println("Map<String, String> result = new HashMap<String, String>();");
for (JType type : getSerializableTypes()) {
String typeString = typeStrings.get(type);
@@ -466,16 +474,8 @@
if (customSerializer != null
&& CustomFieldSerializerValidator.getConcreteTypeMethod(customSerializer) != null) {
typeRef = customSerializer.getQualifiedSourceName() + ".concreteType()";
- } else if (type instanceof JClassType) {
- typeRef = SerializationUtils.getStandardSerializerName((JClassType) type)
- + ".concreteType()";
} else {
- typeRef = type.getLeafType().getQualifiedSourceName();
- while (type.isArray() != null) {
- typeRef += "[]";
- type = type.isArray().getComponentType();
- }
- typeRef += ".class";
+ typeRef = '"' + SerializationUtils.getRpcTypeName(type) + '"';
}
srcWriter.println("result.put(" + typeRef + ", \"" + typeString + "\");");
@@ -501,6 +501,7 @@
*/
private void writeLoadSignaturesNative() {
srcWriter.println("@SuppressWarnings(\"deprecation\")");
+ srcWriter.println("@GwtScriptOnly");
srcWriter.println("private static native JsArrayString loadSignaturesNative() /*-{");
srcWriter.indent();
srcWriter.println("var result = [];");
@@ -550,16 +551,16 @@
* Writes the class's static fields.
*
* <pre>
- * private static final Map<String, TypeHandler> methodMapJava;
+ * private static final Map<String, String> methodMapJava;
* private static final MethodMap methodMapNative;
- * private static final Map<Class<?>, String> signatureMapJava;
+ * private static final Map<String<?>, String> signatureMapJava;
* private static final JsArrayString signatureMapNative;
* </pre>
*/
private void writeStaticFields() {
- srcWriter.println("private static final Map<String, TypeHandler> methodMapJava;");
+ srcWriter.println("private static final Map<String, String> methodMapJava;");
srcWriter.println("private static final MethodMap methodMapNative;");
- srcWriter.println("private static final Map<Class<?>, String> signatureMapJava;");
+ srcWriter.println("private static final Map<String, String> signatureMapJava;");
srcWriter.println("private static final JsArrayString signatureMapNative;");
srcWriter.println();
}
diff --git a/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/impl/ReflectionHelper.java b/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/impl/ReflectionHelper.java
new file mode 100644
index 0000000..e77b80c
--- /dev/null
+++ b/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/impl/ReflectionHelper.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.rpc.impl;
+
+import com.google.gwt.core.client.GwtScriptOnly;
+
+/**
+ * The script-mode equivalent for ReflectionHelper. This version throws
+ * exceptions if used, because ReflectionHelper can only be used from bytecode.
+ */
+@GwtScriptOnly
+public class ReflectionHelper {
+ public static Class<?> loadClass(String name) throws Exception {
+ throw new RuntimeException("ReflectionHelper can't be used from web mode.");
+ }
+
+ public static <T> T newInstance(Class<T> klass)
+ throws Exception {
+ throw new RuntimeException("ReflectionHelper can't be used from web mode.");
+ }
+}