Fixes the java.utils.Arrays.ArrayList problem. Do not create a covariant array for a subtype that is not visible to other types in the same package. Updated logging for exposure information.
Review by: mmendez, spoon (pair prog)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2873 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
index 3a9bf67..a347f8a 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
@@ -502,7 +502,7 @@
* the same package.
*/
private static boolean isAccessibleToClassesInSamePackage(JClassType type) {
- if (type.isPrivate()) {
+ if (type.isPrivate() || type.isLocalType()) {
return false;
}
@@ -761,6 +761,21 @@
if (leafClass != null) {
JClassType[] leafSubtypes = leafClass.getErasedType().getSubtypes();
for (JClassType leafSubtype : leafSubtypes) {
+ if (leafSubtype.isRawType() != null) {
+ /*
+ * Convert from a generic type into a parameterization of the said
+ * generic type where each argument is the type argument. The goal
+ * is have checkTypeInstantiable not check the type parameters.
+ */
+ JGenericType leafGenericSub = leafSubtype.isRawType().getBaseType();
+ leafSubtype = typeOracle.getParameterizedType(leafGenericSub,
+ leafGenericSub.getTypeParameters());
+ }
+
+ if (!isAccessibleToClassesInSamePackage(leafSubtype)) {
+ continue;
+ }
+
JArrayType covariantArray = getArrayType(typeOracle,
isArray.getRank(), leafSubtype);
checkTypeInstantiable(localLogger, covariantArray, true, path);
@@ -879,6 +894,11 @@
Path subtypePath = createSubtypePath(path, subtype, originalType);
boolean subInstantiable = checkTypeInstantiableNoSubtypes(
subtypeLogger, subtype, true, subtypePath);
+ if (!subInstantiable) {
+ // If the subtype is not instantiable do not check the arguments.
+ continue;
+ }
+
JGenericType genericSub = subtype.isGenericType();
if (genericSub != null) {
TreeLogger paramsLogger = subtypeLogger.branch(TreeLogger.DEBUG,
@@ -914,7 +934,7 @@
* included. In order to be certain, we would need to perform a full
* unification between the query type and subtype.
*/
- if (subInstantiable && isParameterized != null) {
+ if (isParameterized != null) {
HashSet<JTypeParameter> typeParamsInQueryType = new HashSet<JTypeParameter>();
recordTypeParametersIn(isParameterized, typeParamsInQueryType);
@@ -1098,6 +1118,7 @@
final JArrayType arrayType, boolean isSpeculative, final Path parent) {
TreeLogger branch = logger.branch(TreeLogger.DEBUG,
"Analyzing component type:", null);
+
return checkTypeInstantiable(branch, arrayType.getComponentType(),
isSpeculative, createArrayComponentPath(arrayType, parent));
}
@@ -1132,7 +1153,9 @@
JField[] fields = classOrInterface.getFields();
if (fields.length > 0) {
TreeLogger localLogger = logger.branch(TreeLogger.DEBUG,
- "Analyzing Fields:", null);
+ "Analyzing the fields of type '"
+ + classOrInterface.getParameterizedQualifiedSourceName()
+ + "' that qualify for serialization", null);
for (JField field : fields) {
if (!qualfiesForSerialization(localLogger, field)) {
@@ -1211,19 +1234,38 @@
Path path = createTypeArgumentPath(parent, baseType, paramIndex, typeArg);
int exposure = getTypeParameterExposure(baseType, paramIndex);
switch (exposure) {
- case EXPOSURE_DIRECT:
- return checkTypeInstantiable(logger, typeArg, true, path)
+ case EXPOSURE_DIRECT: {
+ TreeLogger branch = logger.branch(
+ TreeLogger.DEBUG,
+ "Checking type argument "
+ + paramIndex
+ + " of type '"
+ + baseType.getParameterizedQualifiedSourceName()
+ + "' because it is directly exposed in this type or in one of its subtypes");
+ return checkTypeInstantiable(branch, typeArg, true, path)
|| mightNotBeExposed(baseType, paramIndex);
-
+ }
case EXPOSURE_NONE:
// Ignore this argument
+ logger.branch(TreeLogger.DEBUG, "Ignoring type argument " + paramIndex
+ + " of type '" + baseType.getParameterizedQualifiedSourceName()
+ + "' because it is not exposed in this or any subtype");
return true;
- default:
+ default: {
assert (exposure >= EXPOSURE_MIN_BOUNDED_ARRAY);
- return checkTypeInstantiable(logger, getArrayType(typeOracle, exposure,
+ TreeLogger branch = logger.branch(
+ TreeLogger.DEBUG,
+ "Checking type argument "
+ + paramIndex
+ + " of type '"
+ + baseType.getParameterizedQualifiedSourceName()
+ + "' because it is exposed as an array with a maximum dimension of "
+ + exposure + " in this type or one of its subtypes");
+ return checkTypeInstantiable(branch, getArrayType(typeOracle, exposure,
typeArg), true, path)
|| mightNotBeExposed(baseType, paramIndex);
+ }
}
}
@@ -1357,7 +1399,6 @@
}
/**
- *
* Returns a map from each parameter in the subtype to the set of parameters,
* if any, in the supertype which constrain that parameter.
*/