From 2f3b2b528d1aa91415a674c48abf3195e0b0b98c Mon Sep 17 00:00:00 2001 From: mjhalupka Date: Tue, 6 Mar 2018 09:40:19 -0800 Subject: Add wildcard support to AutoCodec. PiperOrigin-RevId: 188034513 --- .../autocodec/AutoCodecProcessor.java | 19 +++++++++-------- .../serialization/autocodec/Marshallers.java | 24 ++++++++++++++-------- 2 files changed, 27 insertions(+), 16 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java index e849f486d3..dd7ad40fc0 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java @@ -52,7 +52,6 @@ import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.type.TypeVariable; import javax.lang.model.util.ElementFilter; import javax.tools.Diagnostic; @@ -161,7 +160,7 @@ public class AutoCodecProcessor extends AbstractProcessor { Modifier.FINAL) .initializer( "$T.$L", - sanitizeTypeParameterOfGenerics(symbol.getEnclosingElement().asType()), + sanitizeTypeParameter(symbol.getEnclosingElement().asType()), symbol.getSimpleName()) .build()) .build(); @@ -233,7 +232,10 @@ public class AutoCodecProcessor extends AbstractProcessor { } private Relation findRelationWithGenerics(TypeMirror type1, TypeMirror type2) { - if (type1.getKind() == TypeKind.TYPEVAR || type2.getKind() == TypeKind.TYPEVAR) { + if (type1.getKind() == TypeKind.TYPEVAR + || type1.getKind() == TypeKind.WILDCARD + || type2.getKind() == TypeKind.TYPEVAR + || type2.getKind() == TypeKind.WILDCARD) { return Relation.EQUAL_TO; } if (env.getTypeUtils().isAssignable(type1, type2)) { @@ -303,9 +305,9 @@ public class AutoCodecProcessor extends AbstractProcessor { TypeKind typeKind = parameter.asType().getKind(); serializeBuilder.addStatement( "$T unsafe_$L = ($T) $T.getInstance().get$L(input, $L_offset)", - sanitizeTypeParameterOfGenerics(parameter.asType()), + sanitizeTypeParameter(parameter.asType()), parameter.getSimpleName(), - sanitizeTypeParameterOfGenerics(parameter.asType()), + sanitizeTypeParameter(parameter.asType()), UnsafeProvider.class, typeKind.isPrimitive() ? firstLetterUpper(typeKind.toString().toLowerCase()) : "Object", parameter.getSimpleName()); @@ -319,8 +321,9 @@ public class AutoCodecProcessor extends AbstractProcessor { return serializeBuilder.build(); } - private TypeMirror sanitizeTypeParameterOfGenerics(TypeMirror type) { - if (type instanceof TypeVariable) { + // Sanitizes the type parameter. If it's a TypeVariable or WildcardType this will get the erasure. + private TypeMirror sanitizeTypeParameter(TypeMirror type) { + if (Marshallers.isVariableOrWildcardType(type)) { return env.getTypeUtils().erasure(type); } if (!(type instanceof DeclaredType)) { @@ -328,7 +331,7 @@ public class AutoCodecProcessor extends AbstractProcessor { } DeclaredType declaredType = (DeclaredType) type; for (TypeMirror typeMirror : declaredType.getTypeArguments()) { - if (typeMirror instanceof TypeVariable) { + if (Marshallers.isVariableOrWildcardType(typeMirror)) { return env.getTypeUtils().erasure(type); } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java index d160cc3519..af8a2da6bb 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java @@ -55,6 +55,7 @@ import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; +import javax.lang.model.type.WildcardType; /** Class containing all {@link Marshaller} instances. */ class Marshallers { @@ -82,15 +83,16 @@ class Marshallers { void writeDeserializationCode(Context context) { SerializationCodeGenerator generator = getMatchingCodeGenerator(context.type); boolean needsNullHandling = context.canBeNull() && generator != contextMarshaller; - // Check to see if this declared type is generic or if it contains a generic. + // If we have a generic or a wildcard parameter we need to erase it when we write the code out. TypeName contextTypeName = context.getTypeName(); if (context.isDeclaredType() && !context.getDeclaredType().getTypeArguments().isEmpty()) { for (TypeMirror paramTypeMirror : context.getDeclaredType().getTypeArguments()) { - if (paramTypeMirror instanceof TypeVariable) { + if (isVariableOrWildcardType(paramTypeMirror)) { contextTypeName = TypeName.get(env.getTypeUtils().erasure(context.getDeclaredType())); } } - } else if (context.getTypeMirror() instanceof TypeVariable) { + // If we're just a generic or wildcard, get the erasure and use that. + } else if (isVariableOrWildcardType(context.getTypeMirror())) { contextTypeName = TypeName.get(env.getTypeUtils().erasure(context.getTypeMirror())); } if (needsNullHandling) { @@ -179,7 +181,7 @@ class Marshallers { } // We're dealing with a generic. - if (type instanceof TypeVariable) { + if (isVariableOrWildcardType(type)) { return contextMarshaller; } @@ -537,8 +539,9 @@ class Marshallers { context.builder.addStatement( "codedOut.writeInt32NoTag($T.size($L))", Iterables.class, context.name); TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0); - if (typeParameter instanceof TypeVariable) { - typeParameter = ((TypeVariable) typeParameter).getUpperBound(); + // If this is generic we have to get the erasure since we don't know what or are. + if (isVariableOrWildcardType(typeParameter)) { + typeParameter = env.getTypeUtils().erasure(typeParameter); } Context repeated = context.with( @@ -554,8 +557,9 @@ class Marshallers { context.with( context.getDeclaredType().getTypeArguments().get(0), context.makeName("repeated")); TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0); - if (typeParameter instanceof TypeVariable) { - typeParameter = ((TypeVariable) typeParameter).getUpperBound(); + // If this is generic we have to get the erasure since we don't know what or are. + if (isVariableOrWildcardType(typeParameter)) { + typeParameter = env.getTypeUtils().erasure(typeParameter); } String builderName = context.makeName("builder"); context.builder.addStatement( @@ -1083,4 +1087,8 @@ class Marshallers { private TypeMirror getType(Class clazz) { return env.getElementUtils().getTypeElement((clazz.getCanonicalName())).asType(); } + + static boolean isVariableOrWildcardType(TypeMirror type) { + return type instanceof TypeVariable || type instanceof WildcardType; + } } -- cgit v1.2.3