Finish botched roll-back of r8752 and r8762. This finished the roll-back start in r8804. Review by: chak@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8806 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 cf8ac75..b4e9673 100644 --- a/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java +++ b/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
@@ -21,20 +21,16 @@ import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.typeinfo.JArrayType; import com.google.gwt.core.ext.typeinfo.JClassType; -import com.google.gwt.core.ext.typeinfo.JConstructor; import com.google.gwt.core.ext.typeinfo.JEnumType; import com.google.gwt.core.ext.typeinfo.JField; -import com.google.gwt.core.ext.typeinfo.JMethod; import com.google.gwt.core.ext.typeinfo.JPrimitiveType; import com.google.gwt.core.ext.typeinfo.JType; -import com.google.gwt.core.ext.typeinfo.JTypeParameter; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.dev.javac.TypeOracleMediator; import com.google.gwt.user.client.rpc.SerializationException; import com.google.gwt.user.client.rpc.SerializationStreamReader; import com.google.gwt.user.client.rpc.SerializationStreamWriter; import com.google.gwt.user.client.rpc.core.java.lang.Object_Array_CustomFieldSerializer; -import com.google.gwt.user.client.rpc.impl.TypeHandler; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; @@ -54,14 +50,6 @@ private static final String WEAK_MAPPING_CLASS_NAME = WeakMapping.class.getName(); - private final JClassType customFieldSerializer; - - private final boolean customFieldSerializerHasInstantiate; - - private final String fieldSerializerName; - - private final boolean isJRE; - private final JClassType serializableClass; private final JField[] serializableFields; @@ -79,9 +67,7 @@ */ public FieldSerializerCreator(TypeOracle typeOracle, SerializableTypeOracle typesSentFromBrowser, - SerializableTypeOracle typesSentToBrowser, JClassType requestedClass, - JClassType customFieldSerializer) { - this.customFieldSerializer = customFieldSerializer; + SerializableTypeOracle typesSentToBrowser, JClassType requestedClass) { assert (requestedClass != null); assert (requestedClass.isClass() != null || requestedClass.isArray() != null); @@ -91,10 +77,6 @@ serializableClass = requestedClass; serializableFields = SerializationUtils.getSerializableFields(typeOracle, requestedClass); - this.fieldSerializerName = SerializationUtils.getStandardSerializerName(serializableClass); - this.isJRE = SerializableTypeOracleBuilder.isInStandardJavaPackage(serializableClass.getQualifiedSourceName()); - this.customFieldSerializerHasInstantiate = (customFieldSerializer != null && CustomFieldSerializerValidator.hasInstantiationMethod( - customFieldSerializer, serializableClass)); } public String realize(TreeLogger logger, GeneratorContext ctx) { @@ -105,18 +87,17 @@ "Generating a field serializer for type '" + serializableClass.getQualifiedSourceName() + "'", null); + String fieldSerializerName = SerializationUtils.getFieldSerializerName( + typeOracle, serializableClass); + sourceWriter = getSourceWriter(logger, ctx); if (sourceWriter == null) { return fieldSerializerName; } assert sourceWriter != null; - maybeWriteTypeHandlerClass(); - writeFieldAccessors(); - writeConcreteTypeMethod(); - writeDeserializeMethod(); maybeWriteInstatiateMethod(); @@ -128,17 +109,6 @@ return fieldSerializerName; } - private boolean classIsAccessible() { - JClassType testClass = serializableClass; - while (testClass != null) { - if (testClass.isPrivate() || (isJRE && !testClass.isPublic())) { - return false; - } - testClass = testClass.getEnclosingType(); - } - return true; - } - private String createArrayInstantiationExpression(JArrayType array) { StringBuilder sb = new StringBuilder(); @@ -151,15 +121,7 @@ return sb.toString(); } - - private boolean ctorIsAccessible() { - JConstructor ctor = serializableClass.findConstructor(new JType[0]); - if (ctor.isPrivate() || (isJRE && !ctor.isPublic())) { - return false; - } - return true; - } - + /** * Returns the depth of the given class in the class hierarchy * (where the depth of java.lang.Object == 0). @@ -173,14 +135,16 @@ } private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) { - int packageNameEnd = fieldSerializerName.lastIndexOf('.'); + String qualifiedSerializerName = SerializationUtils.getFieldSerializerName( + typeOracle, serializableClass); + int packageNameEnd = qualifiedSerializerName.lastIndexOf('.'); String className; String packageName; if (packageNameEnd != -1) { - className = fieldSerializerName.substring(packageNameEnd + 1); - packageName = fieldSerializerName.substring(0, packageNameEnd); + className = qualifiedSerializerName.substring(packageNameEnd + 1); + packageName = qualifiedSerializerName.substring(0, packageNameEnd); } else { - className = fieldSerializerName; + className = qualifiedSerializerName; packageName = ""; } @@ -191,29 +155,10 @@ ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory( packageName, className); - composerFactory.addImport(SerializationException.class.getCanonicalName()); - composerFactory.addImport(SerializationStreamReader.class.getCanonicalName()); - composerFactory.addImport(SerializationStreamWriter.class.getCanonicalName()); composerFactory.addAnnotationDeclaration("@SuppressWarnings(\"deprecation\")"); return composerFactory.createSourceWriter(ctx, printWriter); } - private String getTypeSig(JMethod deserializationMethod) { - JTypeParameter[] typeParameters = deserializationMethod.getTypeParameters(); - String typeSig = ""; - if (typeParameters.length > 0) { - StringBuilder sb = new StringBuilder(); - sb.append('<'); - for (JTypeParameter typeParameter : typeParameters) { - sb.append(typeParameter.getFirstBound().getQualifiedSourceName()); - sb.append(','); - } - sb.setCharAt(sb.length() - 1, '>'); - typeSig = sb.toString(); - } - return typeSig; - } - private void maybeSuppressLongWarnings(JType fieldType) { if (fieldType == JPrimitiveType.LONG) { /** @@ -245,25 +190,17 @@ return; } - if (customFieldSerializerHasInstantiate) { - // The custom field serializer already defined it. - return; - } - JArrayType isArray = serializableClass.isArray(); JEnumType isEnum = serializableClass.isEnum(); - JClassType isClass = serializableClass.isClass(); + boolean isNative = (isArray == null) && (isEnum == null); - boolean useViolator = false; - if (isEnum == null && isClass != null) { - useViolator = !classIsAccessible() || !ctorIsAccessible(); - } - - sourceWriter.print("public static" + (useViolator ? " native " : " ")); + sourceWriter.print("public static" + (isNative ? " native " : " ")); String qualifiedSourceName = serializableClass.getQualifiedSourceName(); sourceWriter.print(qualifiedSourceName); - sourceWriter.print(" instantiate(SerializationStreamReader streamReader) throws SerializationException " - + (useViolator ? "/*-{" : "{")); + sourceWriter.print(" instantiate("); + sourceWriter.print(SerializationStreamReader.class.getName()); + sourceWriter.println(" streamReader) throws " + + SerializationException.class.getName() + (isNative ? "/*-{" : "{")); sourceWriter.indent(); if (isArray != null) { @@ -276,100 +213,15 @@ + qualifiedSourceName + ".values();"); sourceWriter.println("assert (ordinal >= 0 && ordinal < values.length);"); sourceWriter.println("return values[ordinal];"); - } else if (useViolator) { + } else { sourceWriter.println("return @" + qualifiedSourceName + "::new()();"); - } else { - sourceWriter.println("return new " + qualifiedSourceName + "();"); } sourceWriter.outdent(); - sourceWriter.println(useViolator ? "}-*/;" : "}"); + sourceWriter.println(isNative ? "}-*/;" : "}"); sourceWriter.println(); } - private void maybeWriteTypeHandlerClass() { - if (serializableClass.isEnum() == null && serializableClass.isAbstract()) { - /* - * Field serializers are shared by all of the RemoteService proxies in a - * compilation. Therefore, we have to generate an instantiate method even - * if the type is not instantiable relative to the RemoteService which - * caused this field serializer to be created. If the type is not - * instantiable relative to any of the RemoteService proxies, dead code - * optimizations will cause the method to be removed from the compiled - * output. - * - * Enumerated types require an instantiate method even if they are - * abstract. You will have an abstract enum in cases where the enum type - * is sub-classed. Non-default instantiable classes cannot have - * instantiate methods. - */ - return; - } - sourceWriter.println("public static class Handler implements " - + TypeHandler.class.getCanonicalName() + " {"); - sourceWriter.indent(); - - // Deserialization method - sourceWriter.println("public void deserialize(SerializationStreamReader reader, Object object) throws SerializationException {"); - if (customFieldSerializer != null) { - JMethod deserializationMethod = CustomFieldSerializerValidator.getDeserializationMethod( - customFieldSerializer, serializableClass); - JType castType = deserializationMethod.getParameters()[1].getType(); - String typeSig = getTypeSig(deserializationMethod); - sourceWriter.indentln(customFieldSerializer.getQualifiedSourceName() - + "." + typeSig + "deserialize(reader, (" - + castType.getQualifiedSourceName() + ")object);"); - } else { - sourceWriter.indentln(fieldSerializerName + ".deserialize(reader, (" - + serializableClass.getQualifiedSourceName() + ")object);"); - } - sourceWriter.println("}"); - - // Instantiation method - sourceWriter.println("public Object instantiate(SerializationStreamReader reader) throws SerializationException {"); - sourceWriter.indent(); - if (serializableClass.isEnum() != null - || serializableClass.isDefaultInstantiable() - || customFieldSerializerHasInstantiate) { - sourceWriter.print("return "); - String typeSig; - if (customFieldSerializer != null && customFieldSerializerHasInstantiate) { - sourceWriter.print(customFieldSerializer.getQualifiedSourceName()); - JMethod instantiationMethod = CustomFieldSerializerValidator.getInstantiationMethod( - customFieldSerializer, serializableClass); - typeSig = getTypeSig(instantiationMethod); - } else { - sourceWriter.print(fieldSerializerName); - typeSig = ""; - } - sourceWriter.print("." + typeSig + "instantiate"); - sourceWriter.println("(reader);"); - } else { - sourceWriter.println("return null;"); - } - sourceWriter.outdent(); - sourceWriter.println("}"); - - // Serialization method - sourceWriter.println("public void serialize(SerializationStreamWriter writer, Object object) throws SerializationException {"); - if (customFieldSerializer != null) { - JMethod serializationMethod = CustomFieldSerializerValidator.getSerializationMethod( - customFieldSerializer, serializableClass); - JType castType = serializationMethod.getParameters()[1].getType(); - String typeSig = getTypeSig(serializationMethod); - sourceWriter.indentln(customFieldSerializer.getQualifiedSourceName() - + "." + typeSig + "serialize(writer, (" - + castType.getQualifiedSourceName() + ")object);"); - } else { - sourceWriter.indentln(fieldSerializerName + ".serialize(writer, (" - + serializableClass.getQualifiedSourceName() + ")object);"); - } - - sourceWriter.println("}"); - sourceWriter.outdent(); - sourceWriter.println("}"); - } - /** * Returns true if we will need a get/set method pair for a field. * @@ -467,9 +319,9 @@ JClassType superClass = serializableClass.getSuperclass(); if (superClass != null && (typesSentFromBrowser.isSerializable(superClass) || typesSentToBrowser.isSerializable(superClass))) { - String superFieldSerializer = SerializationUtils.getFieldSerializerName( + String fieldSerializerName = SerializationUtils.getFieldSerializerName( typeOracle, superClass); - sourceWriter.print(superFieldSerializer); + sourceWriter.print(fieldSerializerName); sourceWriter.println(".deserialize(streamReader, instance);"); } } @@ -511,41 +363,20 @@ JClassType superClass = serializableClass.getSuperclass(); if (superClass != null && (typesSentFromBrowser.isSerializable(superClass) || typesSentToBrowser.isSerializable(superClass))) { - String superFieldSerializer = SerializationUtils.getFieldSerializerName( + String fieldSerializerName = SerializationUtils.getFieldSerializerName( typeOracle, superClass); - sourceWriter.print(superFieldSerializer); + sourceWriter.print(fieldSerializerName); sourceWriter.println(".serialize(streamWriter, instance);"); } } - 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 = TypeOracleMediator.computeBinaryClassName(serializableClass); - sourceWriter.println("public static native Class<?> concreteType() /*-{"); - sourceWriter.indentln("return @" + jsniTypeRef + "::class;"); - sourceWriter.println("}-*/;"); - sourceWriter.println(); - } - } - private void writeDeserializeMethod() { - if (customFieldSerializer != null) { - return; - } - sourceWriter.print("public static void deserialize(SerializationStreamReader streamReader, "); + sourceWriter.print("public static void deserialize("); + sourceWriter.print(SerializationStreamReader.class.getName()); + sourceWriter.print(" streamReader, "); sourceWriter.print(serializableClass.getQualifiedSourceName()); - sourceWriter.println(" instance) throws SerializationException {"); + sourceWriter.println(" instance) throws " + + SerializationException.class.getName() + "{"); sourceWriter.indent(); JArrayType isArray = serializableClass.isArray(); @@ -577,9 +408,6 @@ * external class to access the field's value. */ private void writeFieldAccessors() { - if (customFieldSerializer != null) { - return; - } for (JField serializableField : serializableFields) { if (!needsAccessorMethods(serializableField)) { continue; @@ -651,12 +479,12 @@ } private void writeSerializeMethod() { - if (customFieldSerializer != null) { - return; - } - sourceWriter.print("public static void serialize(SerializationStreamWriter streamWriter, "); + sourceWriter.print("public static void serialize("); + sourceWriter.print(SerializationStreamWriter.class.getName()); + sourceWriter.print(" streamWriter, "); sourceWriter.print(serializableClass.getQualifiedSourceName()); - sourceWriter.println(" instance) throws SerializationException {"); + sourceWriter.println(" instance) throws " + + SerializationException.class.getName() + " {"); sourceWriter.indent(); JArrayType isArray = serializableClass.isArray();
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 7487759..04eb528 100644 --- a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java +++ b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
@@ -16,7 +16,7 @@ package com.google.gwt.user.rebind.rpc; -import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.core.ext.BadPropertyValueException; import com.google.gwt.core.ext.ConfigurationProperty; @@ -32,8 +32,8 @@ import com.google.gwt.user.client.rpc.SerializationException; import com.google.gwt.user.client.rpc.SerializationStreamReader; import com.google.gwt.user.client.rpc.SerializationStreamWriter; +import com.google.gwt.user.client.rpc.impl.Serializer; import com.google.gwt.user.client.rpc.impl.SerializerBase; -import com.google.gwt.user.client.rpc.impl.TypeHandler; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; @@ -41,7 +41,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.List; @@ -103,28 +102,24 @@ private final boolean elideTypeNames; - private final JType[] serializableTypes; - private final SerializableTypeOracle serializationOracle; + private final JType[] serializableTypes; + private final SourceWriter srcWriter; private final TypeOracle typeOracle; private final String typeSerializerClassName; - private final String typeSerializerSimpleName; - private final Map<JType, String> typeStrings = new IdentityHashMap<JType, String>(); public TypeSerializerCreator(TreeLogger logger, SerializableTypeOracle serializationOracle, SerializableTypeOracle deserializationOracle, GeneratorContext context, - String typeSerializerClassName, String typeSerializerSimpleName) - throws UnableToCompleteException { + String typeSerializerClassName) throws UnableToCompleteException { this.context = context; this.typeSerializerClassName = typeSerializerClassName; - this.typeSerializerSimpleName = typeSerializerSimpleName; this.serializationOracle = serializationOracle; this.deserializationOracle = deserializationOracle; @@ -164,41 +159,29 @@ public String realize(TreeLogger logger) { logger = logger.branch(TreeLogger.DEBUG, "Generating TypeSerializer for service interface '" - + typeSerializerClassName + "'", null); + + getTypeSerializerClassName() + "'", null); + String typeSerializerName = getTypeSerializerClassName(); + if (srcWriter == null) { + return typeSerializerName; + } createFieldSerializers(logger, context); - int index = 0; - for (JType type : getSerializableTypes()) { + writeStaticFields(); - String typeString; - if (elideTypeNames) { - typeString = Integer.toString(++index, Character.MAX_RADIX); - } else { - typeString = getTypeString(type); - } - typeStrings.put(type, typeString); - } + writeStaticInitializer(); - if (srcWriter != null) { - writeStaticFields(); + writeCreateMethods(); - writeStaticInitializer(); + writeRegisterSignatures(); - writeLoadMethodsJava(); + writeRegisterMethods(); - writeLoadMethodsNative(); + writeRaiseSerializationException(); - writeLoadSignaturesJava(); + srcWriter.commit(logger); - writeLoadSignaturesNative(); - - writeConstructor(); - - srcWriter.commit(logger); - } - - return typeSerializerClassName; + return typeSerializerName; } /* @@ -216,6 +199,12 @@ return; } + JClassType customFieldSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( + typeOracle, type); + if (customFieldSerializer != null) { + return; + } + /* * Only a JClassType can reach this point in the code. JPrimitives have been * removed because their serialization is built in, interfaces have been @@ -224,11 +213,8 @@ */ assert (type.isClass() != null || type.isArray() != null); - JClassType customFieldSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( - typeOracle, type); FieldSerializerCreator creator = new FieldSerializerCreator(typeOracle, - serializationOracle, deserializationOracle, (JClassType) type, - customFieldSerializer); + serializationOracle, deserializationOracle, (JClassType) type); creator.realize(logger, ctx); } @@ -246,6 +232,14 @@ } } + private String getCreateMethodName(JType type) { + assert (type.isArray() == null); + + return "create_" + + SerializationUtils.getFieldSerializerName(typeOracle, type).replace( + '.', '_'); + } + private String[] getPackageAndClassName(String fullClassName) { String className = fullClassName; String packageName = ""; @@ -262,7 +256,7 @@ } private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) { - String name[] = getPackageAndClassName(typeSerializerClassName); + String name[] = getPackageAndClassName(getTypeSerializerClassName()); String packageName = name[0]; String className = name[1]; PrintWriter printWriter = ctx.tryCreate(logger, packageName, className); @@ -273,19 +267,21 @@ ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory( packageName, className); - composerFactory.addImport(GWT.class.getName()); + composerFactory.addImport(JavaScriptObject.class.getName()); composerFactory.addImport(JsArrayString.class.getName()); + composerFactory.addImport(Serializer.class.getName()); composerFactory.addImport(SerializationException.class.getName()); composerFactory.addImport(SerializationStreamReader.class.getName()); composerFactory.addImport(SerializationStreamWriter.class.getName()); - composerFactory.addImport(TypeHandler.class.getName()); - composerFactory.addImport(HashMap.class.getName()); - composerFactory.addImport(Map.class.getName()); composerFactory.setSuperclass(SerializerBase.class.getName()); return composerFactory.createSourceWriter(ctx, printWriter); } + private String getTypeSerializerClassName() { + return typeSerializerClassName; + } + /** * @param type * @return @@ -297,56 +293,78 @@ } /** - * Return <code>true</code> if the custom field serializer has an instantiate - * method. + * Return <code>true</code> if this type is concrete and has a custom field + * serializer that does not declare an instantiate method. + * + * @param type + * @return */ - private boolean hasInstantiateMethod(JClassType customSerializer, JType type) { - return CustomFieldSerializerValidator.getInstantiationMethod( - customSerializer, (JClassType) type) != null; + private boolean needsCreateMethod(JType type) { + // If this type is abstract it will not be serialized into the stream + // + if (!deserializationOracle.maybeInstantiated(type)) { + return false; + } + + if (type.isArray() != null) { + return false; + } + + JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( + typeOracle, type); + if (customSerializer == null) { + return false; + } + + JMethod customInstantiate = customSerializer.findMethod( + "instantiate", + new JType[] {typeOracle.findType(SerializationStreamReader.class.getName())}); + if (customInstantiate != null) { + return false; + } + + return true; } - private void writeConstructor() { - srcWriter.println("public " + typeSerializerSimpleName + "() {"); - srcWriter.indentln("super(methodMapJava, methodMapNative, signatureMapJava, signatureMapNative);"); - srcWriter.println("}"); - srcWriter.println(); - } - - private void writeLoadMethodsJava() { - srcWriter.println("private static Map<String, TypeHandler> loadMethodsJava() {"); - srcWriter.indent(); - srcWriter.println("Map<String, TypeHandler> result = new HashMap<String, TypeHandler>();"); - - List<JType> filteredTypes = new ArrayList<JType>(); + private void writeCreateMethods() { JType[] types = getSerializableTypes(); - int n = types.length; - for (int index = 0; index < n; ++index) { - JType type = types[index]; - if (serializationOracle.maybeInstantiated(type) - || deserializationOracle.maybeInstantiated(type)) { - filteredTypes.add(type); + for (int typeIndex = 0; typeIndex < types.length; ++typeIndex) { + JType type = types[typeIndex]; + assert (serializationOracle.isSerializable(type) || deserializationOracle.isSerializable(type)); + + if (!needsCreateMethod(type)) { + continue; } - } - for (JType type : filteredTypes) { - String typeString = typeStrings.get(type); - assert typeString != null : "Missing type signature for " - + type.getQualifiedSourceName(); - srcWriter.println("result.put(\"" + typeString + "\", new " - + SerializationUtils.getStandardSerializerName((JClassType) type) - + ".Handler());"); + /* + * Only classes with custom field serializers that do no declare + * instantiate methods get here + */ + srcWriter.print("private static native "); + srcWriter.print(type.getQualifiedSourceName()); + srcWriter.print(" "); + srcWriter.print(getCreateMethodName(type)); + srcWriter.println("(SerializationStreamReader streamReader) throws SerializationException /*-{"); + srcWriter.indent(); + srcWriter.print("return @"); + srcWriter.print(type.getQualifiedSourceName()); + srcWriter.println("::new()();"); + srcWriter.outdent(); + srcWriter.println("}-*/;"); + srcWriter.println(); } + } - srcWriter.println("return result;"); - srcWriter.outdent(); + private void writeRaiseSerializationException() { + srcWriter.println("private static void raiseSerializationException(String msg) throws SerializationException {"); + srcWriter.indentln("throw new SerializationException(msg);"); srcWriter.println("}"); srcWriter.println(); } - private void writeLoadMethodsNative() { - srcWriter.println("private static native MethodMap loadMethodsNative() /*-{"); + private void writeRegisterMethods() { + srcWriter.println("private static native void registerMethods() /*-{"); srcWriter.indent(); - srcWriter.println("var result = {};"); List<JType> filteredTypes = new ArrayList<JType>(); JType[] types = getSerializableTypes(); @@ -372,16 +390,23 @@ srcWriter.println("(function() {"); } + srcWriter.println("@com.google.gwt.user.client.rpc.impl.SerializerBase" + + "::registerMethods(" + + "Lcom/google/gwt/user/client/rpc/impl/SerializerBase$MethodMap;" + + "Ljava/lang/String;" + "Lcom/google/gwt/core/client/JsArray;)("); + + srcWriter.indentln("@" + typeSerializerClassName + "::methodMap,"); + String typeString = typeStrings.get(type); assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName(); - srcWriter.println("result[\"" + typeString + "\"] = ["); + srcWriter.indentln("\"" + typeString + "\" , ["); srcWriter.indent(); - writeTypeMethodsNative(type); + writeTypeMethods(type); srcWriter.outdent(); - srcWriter.indentln("];"); + srcWriter.indentln("]);"); srcWriter.println(); } @@ -389,57 +414,16 @@ srcWriter.println("})();"); } - srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}-*/;"); srcWriter.println(); } - private void writeLoadSignaturesJava() { - srcWriter.println("private static Map<Class<?>, String> loadSignaturesJava() {"); + private void writeRegisterSignatures() { + srcWriter.println("private static native void registerSignatures() /*-{"); srcWriter.indent(); - srcWriter.println("Map<Class<?>, String> result = new HashMap<Class<?>, String>();"); - for (JType type : getSerializableTypes()) { - String typeString = typeStrings.get(type); - - if (!serializationOracle.maybeInstantiated(type) - && !deserializationOracle.maybeInstantiated(type)) { - continue; - } - - String typeRef; - JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( - typeOracle, type); - 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"; - } - - srcWriter.println("result.put(" + typeRef + ", \"" + typeString + "\");"); - } - - srcWriter.println("return result;"); - srcWriter.outdent(); - srcWriter.println("}"); - srcWriter.println(); - } - - private void writeLoadSignaturesNative() { - srcWriter.println("private static native JsArrayString loadSignaturesNative() /*-{"); - srcWriter.indent(); - srcWriter.println("var result = [];"); - + int index = 0; boolean shard = shardSize > 0 && getSerializableTypes().length > shardSize; int shardCount = 0; @@ -448,7 +432,14 @@ } for (JType type : getSerializableTypes()) { - String typeString = typeStrings.get(type); + + String typeString; + if (elideTypeNames) { + typeString = Integer.toString(++index, Character.MAX_RADIX); + } else { + typeString = getTypeString(type); + } + typeStrings.put(type, typeString); if (!serializationOracle.maybeInstantiated(type) && !deserializationOracle.maybeInstantiated(type)) { @@ -467,80 +458,71 @@ srcWriter.println("(function() {"); } - srcWriter.println("result[@com.google.gwt.core.client.impl.Impl::getHashCode(Ljava/lang/Object;)(@" - + jsniTypeRef + "::class)] = \"" + typeString + "\";"); + srcWriter.println("@com.google.gwt.user.client.rpc.impl.SerializerBase" + + "::registerSignature(" + + "Lcom/google/gwt/core/client/JsArrayString;" + "Ljava/lang/Class;" + + "Ljava/lang/String;)("); + srcWriter.indent(); + srcWriter.println("@" + typeSerializerClassName + "::signatureMap,"); + srcWriter.println("@" + jsniTypeRef + "::class,"); + srcWriter.println("\"" + typeString + "\");"); + srcWriter.outdent(); + srcWriter.println(); } if (shard) { srcWriter.println("})();"); } - srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}-*/;"); srcWriter.println(); } private void writeStaticFields() { - srcWriter.println("private static final Map<String, TypeHandler> methodMapJava;"); - srcWriter.println("private static final MethodMap methodMapNative;"); - srcWriter.println("private static final Map<Class<?>, String> signatureMapJava;"); - srcWriter.println("private static final JsArrayString signatureMapNative;"); + srcWriter.println("private static final MethodMap methodMap = JavaScriptObject.createObject().cast();"); + srcWriter.println("private static final JsArrayString signatureMap = JavaScriptObject.createArray().cast();"); + srcWriter.println("protected MethodMap getMethodMap() { return methodMap; }"); + srcWriter.println("protected JsArrayString getSignatureMap() { return signatureMap; }"); srcWriter.println(); } private void writeStaticInitializer() { srcWriter.println("static {"); - srcWriter.indent(); - srcWriter.println("if (GWT.isScript()) {"); - srcWriter.indent(); - srcWriter.println("methodMapJava = null;"); - srcWriter.println("methodMapNative = loadMethodsNative();"); - srcWriter.println("signatureMapJava = null;"); - srcWriter.println("signatureMapNative = loadSignaturesNative();"); - srcWriter.outdent(); - srcWriter.println("} else {"); - srcWriter.indent(); - srcWriter.println("methodMapJava = loadMethodsJava();"); - srcWriter.println("methodMapNative = null;"); - srcWriter.println("signatureMapJava = loadSignaturesJava();"); - srcWriter.println("signatureMapNative = null;"); - srcWriter.outdent(); - srcWriter.println("}"); - srcWriter.outdent(); + srcWriter.indentln("registerMethods();"); + srcWriter.indentln("registerSignatures();"); srcWriter.println("}"); } /** - * Write an entry in the methodMapNative for one type. + * Write an entry in the createMethodMap method for one type. * * @param type type to generate entry for */ - private void writeTypeMethodsNative(JType type) { + private void writeTypeMethods(JType type) { srcWriter.indent(); String serializerName = SerializationUtils.getFieldSerializerName( typeOracle, type); - JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( - typeOracle, type); // First the initialization method if (deserializationOracle.maybeInstantiated(type)) { srcWriter.print("@"); - if (customSerializer != null) { - if (hasInstantiateMethod(customSerializer, type)) { - srcWriter.print(serializerName); - } else { - srcWriter.print(SerializationUtils.getStandardSerializerName((JClassType) type)); - } + if (needsCreateMethod(type)) { + srcWriter.print(getTypeSerializerClassName()); + srcWriter.print("::"); + srcWriter.print(getCreateMethodName(type)); } else { srcWriter.print(serializerName); + srcWriter.print("::instantiate"); } - srcWriter.print("::instantiate"); srcWriter.print("(L" + SerializationStreamReader.class.getName().replace('.', '/') + ";)"); } srcWriter.println(","); + JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( + typeOracle, type); + // Now the deserialization method if (deserializationOracle.isSerializable(type)) { // Assume param type is the concrete type of the serialized type.