Fixes issue 1081. The RPC proxy generator was rebuilding the serializable type oracle needlessly. It appears to have always done this. In this fix, I moved the building of the SerializableTypeOracle into the ProxyCreator after we determine that we actually need to regenerate the proxy code. We could refactor the code further but rather than add more risk, we chose to keep it to the minimal change.
If your RemoteService interface triggerred one of the new RPC warnings, you could end up with a lot more log messages than you should.
Found by: jason.essington
Patch by: mmendez
Review by: bruce
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1073 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/eclipse/settings/english.dictionary b/eclipse/settings/english.dictionary
index d0698e5..f6494a3 100644
--- a/eclipse/settings/english.dictionary
+++ b/eclipse/settings/english.dictionary
@@ -47261,3 +47261,4 @@
io
util
serializers
+proxy
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 5e2a604..3559feb 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
@@ -19,6 +19,7 @@
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPackage;
@@ -39,12 +40,11 @@
import com.google.gwt.user.rebind.SourceWriter;
import java.io.PrintWriter;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Set;
/**
- * Creates client-side proxies for remote services.
+ * Creates a client-side proxy for a
+ * {@link com.google.gwt.user.client.rpc.RemoteService RemoteService} interface
+ * as well as the necessary type and field serializers.
*/
class ProxyCreator {
private static final String ENTRY_POINT_TAG = "gwt.defaultEntryPoint";
@@ -58,21 +58,6 @@
+ " streamWriter = new "
+ ClientSerializationStreamWriter.class.getName() + "(SERIALIZER);";
- private static String createOverloadSignature(JMethod method) {
- StringBuffer sb = new StringBuffer();
- sb.append(method.getName());
- sb.append('(');
- JParameter[] params = method.getParameters();
- for (int i = 0; i < params.length; ++i) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(params[i].getType().getQualifiedSourceName());
- }
- sb.append(')');
- return sb.toString();
- }
-
/*
* This method returns the real type name. Currently, it only affects
* JParameterizedType since their names are not legal Java names.
@@ -88,35 +73,43 @@
private boolean enforceTypeVersioning;
- private SerializableTypeOracle serializableTypeOracle;
-
private JClassType serviceIntf;
- public ProxyCreator(JClassType serviceIntf,
- SerializableTypeOracle serializableTypeOracle) {
+ public ProxyCreator(JClassType serviceIntf) {
assert (serviceIntf.isInterface() != null);
-
+
this.serviceIntf = serviceIntf;
- this.serializableTypeOracle = serializableTypeOracle;
}
/**
- * Creates a proxy class for the requested class.
+ * Creates the client-side proxy class.
+ *
+ * @throws UnableToCompleteException
*/
- public String create(TreeLogger logger, GeneratorContext context) {
+ public String create(TreeLogger logger, GeneratorContext context)
+ throws UnableToCompleteException {
SourceWriter srcWriter = getSourceWriter(logger, context);
if (srcWriter == null) {
return getProxyQualifiedName();
}
+ SerializableTypeOracleBuilder stob = new SerializableTypeOracleBuilder(
+ logger, context.getTypeOracle());
+ SerializableTypeOracle sto = stob.build(context.getPropertyOracle(),
+ serviceIntf);
+
+ TypeSerializerCreator tsc = new TypeSerializerCreator(logger, sto, context,
+ serviceIntf);
+ tsc.realize(logger);
+
enforceTypeVersioning = Shared.shouldEnforceTypeVersioning(logger,
context.getPropertyOracle());
- generateProxyFields(srcWriter);
+ generateProxyFields(srcWriter, sto);
generateServiceDefTargetImpl(srcWriter);
- generateProxyMethods(srcWriter);
+ generateProxyMethods(srcWriter, sto);
srcWriter.commit(logger);
@@ -124,8 +117,9 @@
}
/*
- * Give a type emit an expression for deserializing that type from a
- * serialization stream.
+ * Given a type emit an expression for calling the correct
+ * SerializationStreamReader method which reads the corresponding
+ * instance out of the stream.
*/
protected final void generateDecodeCall(SourceWriter w, JType type) {
w.print("streamReader.");
@@ -133,8 +127,8 @@
}
/*
- * Give a type emit an expression for serializing that type into a
- * serialization stream.
+ * Given a type emit an expression for calling the correct
+ * SerializationStreamWriter method which writes that type into the stream.
*/
protected void generateEncodeCall(SourceWriter w, JParameter parameter) {
JType paramType = parameter.getType();
@@ -326,8 +320,7 @@
* Generate the code that addresses the service.
*/
private void generateProxyEncode(SourceWriter w,
- SerializableTypeOracle serializableTypeOracle, JClassType serviceIntf,
- JMethod method) {
+ SerializableTypeOracle serializableTypeOracle, JMethod method) {
String methodName = method.getName();
JParameter[] params = method.getParameters();
w.println();
@@ -359,7 +352,8 @@
+ ".SERIALIZATION_STREAM_FLAGS_NO_TYPE_VERSIONING);");
}
w.println("streamWriter.writeString(\""
- + serializableTypeOracle.getSerializedTypeName(serviceIntf) + "\");");
+ + serializableTypeOracle.getSerializedTypeName(method.getEnclosingType())
+ + "\");");
w.println("streamWriter.writeString(\"" + methodName + "\");");
w.println("streamWriter.writeInt(" + params.length + ");");
for (int i = 0; i < params.length; ++i) {
@@ -383,37 +377,21 @@
/**
* Generate any fields required by the proxy.
*/
- private void generateProxyFields(SourceWriter srcWriter) {
+ private void generateProxyFields(SourceWriter srcWriter,
+ SerializableTypeOracle serializableTypeOracle) {
String typeSerializerName = serializableTypeOracle.getTypeSerializerQualifiedName(serviceIntf);
srcWriter.println("private static final " + typeSerializerName
+ " SERIALIZER = new " + typeSerializerName + "();");
}
- /**
- * @param ctx
- * @param w
- */
- private void generateProxyMethods(SourceWriter w) {
- Set seenMethods = new HashSet();
- LinkedList workList = new LinkedList();
- workList.addLast(serviceIntf);
- while (!workList.isEmpty()) {
- JClassType curIntf = (JClassType) workList.removeFirst();
- JMethod[] methods = curIntf.getMethods();
- for (int index = 0; index < methods.length; ++index) {
- JMethod method = methods[index];
- assert (method != null);
- String signature = createOverloadSignature(method);
- if (!seenMethods.contains(signature)) {
- seenMethods.add(signature);
- generateProxyEncode(w, serializableTypeOracle, curIntf, method);
- generateAsynchronousProxyMethod(w, method);
- }
- }
- JClassType[] interfaces = curIntf.getImplementedInterfaces();
- for (int index = 0; index < interfaces.length; ++index) {
- workList.addLast(interfaces[index]);
- }
+ private void generateProxyMethods(SourceWriter w,
+ SerializableTypeOracle serializableTypeOracle) {
+
+ JMethod[] methods = serviceIntf.getOverridableMethods();
+ for (int i = 0; i < methods.length; ++i) {
+ JMethod method = methods[i];
+ generateProxyEncode(w, serializableTypeOracle, method);
+ generateAsynchronousProxyMethod(w, method);
}
}
diff --git a/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java b/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java
index f7b33b3..57f4cb0 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java
@@ -23,8 +23,8 @@
import com.google.gwt.core.ext.typeinfo.TypeOracle;
/**
- * Generator for producing the asynchronous version of a {@link RemoteService}
- * interface.
+ * Generator for producing the asynchronous version of a
+ * {@link com.google.gwt.user.client.rpc.RemoteService RemoteService} interface.
*/
public class ServiceInterfaceProxyGenerator extends Generator {
@@ -47,33 +47,12 @@
throw new UnableToCompleteException();
}
- logger = logger.branch(TreeLogger.DEBUG,
+ ProxyCreator proxyCreator = new ProxyCreator(remoteService);
+
+ TreeLogger proxyLogger = logger.branch(TreeLogger.DEBUG,
"Generating client proxy for remote service interface '"
+ remoteService.getQualifiedSourceName() + "'", null);
-
- SerializableTypeOracleBuilder stob = new SerializableTypeOracleBuilder(
- logger, typeOracle);
- SerializableTypeOracle sto = stob.build(ctx.getPropertyOracle(),
- remoteService);
- generateTypeSerializer(logger, ctx, remoteService, sto);
-
- return generateProxy(logger, ctx, remoteService, sto);
- }
-
- private String generateProxy(TreeLogger logger, GeneratorContext ctx,
- JClassType serviceIntf, SerializableTypeOracle serializableTypeOracle) {
- ProxyCreator proxyCreator = new ProxyCreator(serviceIntf,
- serializableTypeOracle);
-
- return proxyCreator.create(logger, ctx);
- }
-
- private String generateTypeSerializer(TreeLogger logger,
- GeneratorContext ctx, JClassType serviceIntf,
- SerializableTypeOracle serializableTypeOracle) {
- TypeSerializerCreator typeSerializerCreator = new TypeSerializerCreator(
- logger, serializableTypeOracle, ctx, serviceIntf);
- return typeSerializerCreator.realize(logger);
+ return proxyCreator.create(proxyLogger, ctx);
}
}
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 ba1f7e8..844ff29 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
@@ -88,13 +88,13 @@
logger = logger.branch(TreeLogger.DEBUG,
"Generating TypeSerializer for service interface '"
+ getServiceInterface().getQualifiedSourceName() + "'", null);
- String generatedTypeNames = serializationOracle.getTypeSerializerQualifiedName(getServiceInterface());
-
- generatedTypeNames += ";" + createFieldSerializers(logger, context);
+ String typeSerializerName = serializationOracle.getTypeSerializerQualifiedName(getServiceInterface());
if (srcWriter == null) {
- return generatedTypeNames;
+ return typeSerializerName;
}
-
+
+ createFieldSerializers(logger, context);
+
writeStaticFields();
writeCreateMethods();
@@ -117,7 +117,7 @@
srcWriter.commit(logger);
- return generatedTypeNames;
+ return typeSerializerName;
}
private String buildArrayInstantiationExpression(JArrayType array) {
@@ -143,19 +143,21 @@
* Create a field serializer for a type if it does not have a custom
* serializer.
*/
- private String createFieldSerializer(TreeLogger logger, GeneratorContext ctx,
+ private void createFieldSerializer(TreeLogger logger, GeneratorContext ctx,
JType type) {
assert (type != null);
assert (serializationOracle.isSerializable(type));
JParameterizedType parameterizedType = type.isParameterized();
if (parameterizedType != null) {
- return createFieldSerializer(logger, ctx, parameterizedType.getRawType());
+ createFieldSerializer(logger, ctx, parameterizedType.getRawType());
+ return;
}
JClassType customFieldSerializer = serializationOracle.hasCustomFieldSerializer(type);
if (customFieldSerializer != null) {
- return customFieldSerializer.getQualifiedSourceName();
+ customFieldSerializer.getQualifiedSourceName();
+ return;
}
/*
@@ -169,27 +171,21 @@
FieldSerializerCreator creator = new FieldSerializerCreator(
serializationOracle, type.isClass());
- return creator.realize(logger, ctx);
+ creator.realize(logger, ctx);
}
/*
* Create all of the necessary field serializers.
*/
- private String createFieldSerializers(TreeLogger logger, GeneratorContext ctx) {
+ private void createFieldSerializers(TreeLogger logger, GeneratorContext ctx) {
JType[] types = getSerializableTypes();
int typeCount = types.length;
- String fieldSerializerNames = "";
for (int typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
JType type = types[typeIndex];
assert (type != null);
- String fieldSerializerName = createFieldSerializer(logger, ctx, type);
- if (fieldSerializerName != null) {
- fieldSerializerNames += fieldSerializerName + ";";
- }
+ createFieldSerializer(logger, ctx, type);
}
-
- return fieldSerializerNames;
}
private JMethod getCustomInstantiateMethod(JType type) {