diff options
author | 2018-02-27 09:00:55 -0800 | |
---|---|---|
committer | 2018-02-27 09:02:27 -0800 | |
commit | 48794a6edac0944ad2ecffc495b765ed10a2a3c9 (patch) | |
tree | fad47be8b7423248b590d12dcc55ca429ebcdb39 /src/main/java/com/google/devtools/build/lib/skyframe | |
parent | 98ed9af727ec6342206d181fcd465e3e83980c52 (diff) |
Tag ParameterFileWriteAction with @AutoCodec.
This requires codecs for CustomCommandLine and a Marshaller for Charset.
Added AutoCodec functionality to generic classes like Iterable<T>.
PiperOrigin-RevId: 187182889
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe')
3 files changed, 99 insertions, 14 deletions
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 1df5f51451..d7c2e8a7fd 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 @@ -49,8 +49,10 @@ import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; 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; @@ -251,9 +253,9 @@ public class AutoCodecProcessor extends AbstractProcessor { TypeKind typeKind = parameter.asType().getKind(); serializeBuilder.addStatement( "$T unsafe_$L = ($T) $T.getInstance().get$L(input, $L_offset)", - parameter.asType(), + sanitizeTypeParameterOfGenerics(parameter.asType()), parameter.getSimpleName(), - parameter.asType(), + sanitizeTypeParameterOfGenerics(parameter.asType()), UnsafeProvider.class, typeKind.isPrimitive() ? firstLetterUpper(typeKind.toString().toLowerCase()) : "Object", parameter.getSimpleName()); @@ -276,6 +278,22 @@ public class AutoCodecProcessor extends AbstractProcessor { return env.getTypeUtils().isAssignable(t1, t2) || env.getTypeUtils().isAssignable(t2, t1); } + private TypeMirror sanitizeTypeParameterOfGenerics(TypeMirror type) { + if (type instanceof TypeVariable) { + return env.getTypeUtils().erasure(type); + } + if (!(type instanceof DeclaredType)) { + return type; + } + DeclaredType declaredType = (DeclaredType) type; + for (TypeMirror typeMirror : declaredType.getTypeArguments()) { + if (typeMirror instanceof TypeVariable) { + return env.getTypeUtils().erasure(type); + } + } + return type; + } + private String findGetterForClass(VariableElement parameter, TypeElement type) { List<ExecutableElement> methods = ElementFilter.methodsIn(env.getElementUtils().getAllMembers(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 fea22ae876..5c78bed826 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 @@ -35,6 +35,8 @@ import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs import com.google.protobuf.AbstractMessage; import com.google.protobuf.ExtensionRegistryLite; import com.google.protobuf.ProtocolMessageEnum; +import com.squareup.javapoet.TypeName; +import java.nio.charset.Charset; import java.util.Collection; import java.util.Comparator; import java.util.LinkedHashMap; @@ -51,6 +53,7 @@ import javax.lang.model.type.DeclaredType; import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; /** Class containing all {@link Marshaller} instances. */ class Marshallers { @@ -78,11 +81,22 @@ 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. + TypeName contextTypeName = context.getTypeName(); + if (context.isDeclaredType() && !context.getDeclaredType().getTypeArguments().isEmpty()) { + for (TypeMirror paramTypeMirror : context.getDeclaredType().getTypeArguments()) { + if (paramTypeMirror instanceof TypeVariable) { + contextTypeName = TypeName.get(env.getTypeUtils().erasure(context.getDeclaredType())); + } + } + } else if (context.getTypeMirror() instanceof TypeVariable) { + contextTypeName = TypeName.get(env.getTypeUtils().erasure(context.getTypeMirror())); + } if (needsNullHandling) { - context.builder.addStatement("$T $L = null", context.getTypeName(), context.name); + context.builder.addStatement("$T $L = null", contextTypeName, context.name); context.builder.beginControlFlow("if (codedIn.readBool())"); } else { - context.builder.addStatement("$T $L", context.getTypeName(), context.name); + context.builder.addStatement("$T $L", contextTypeName, context.name); } generator.addDeserializationCode(context); if (needsNullHandling) { @@ -123,6 +137,11 @@ class Marshallers { .orElseThrow(() -> new IllegalArgumentException("No generator for: " + primitiveType)); } + // We're dealing with a generic. + if (type instanceof TypeVariable) { + return contextMarshaller; + } + // TODO(cpeyser): Refactor primitive handling from AutoCodecProcessor.java if (!(type instanceof DeclaredType)) { throw new IllegalArgumentException( @@ -476,11 +495,15 @@ class Marshallers { // Writes the target count to the stream so deserialization knows when to stop. 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(); + } Context repeated = context.with( context.getDeclaredType().getTypeArguments().get(0), context.makeName("repeated")); - context.builder.beginControlFlow( - "for ($T $L : $L)", repeated.getTypeName(), repeated.name, context.name); + context.builder.beginControlFlow( + "for ($T $L : $L)", typeParameter, repeated.name, context.name); writeSerializationCode(repeated); context.builder.endControlFlow(); } @@ -489,14 +512,18 @@ class Marshallers { Context repeated = context.with( context.getDeclaredType().getTypeArguments().get(0), context.makeName("repeated")); - String builderName = context.makeName("builder"); - context.builder.addStatement( - "$T<$T> $L = new $T<>()", - ImmutableList.Builder.class, - repeated.getTypeName(), - builderName, - ImmutableList.Builder.class); - writeListDeserializationLoopAndBuild(context, repeated, builderName); + TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0); + if (typeParameter instanceof TypeVariable) { + typeParameter = ((TypeVariable) typeParameter).getUpperBound(); + } + String builderName = context.makeName("builder"); + context.builder.addStatement( + "$T<$T> $L = new $T<>()", + ImmutableList.Builder.class, + typeParameter, + builderName, + ImmutableList.Builder.class); + writeListDeserializationLoopAndBuild(context, repeated, builderName); } private final Marshaller iterableMarshaller = @@ -883,6 +910,9 @@ class Marshallers { private void addSerializationCodeForNestedSet(Context context) { TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0); + if (typeParameter instanceof TypeVariable) { + typeParameter = ((TypeVariable) typeParameter).getUpperBound(); + } String nestedSetCodec = context.makeName("nestedSetCodec"); context.builder.addStatement( "$T<$T> $L = new $T<>()", @@ -901,6 +931,9 @@ class Marshallers { private void addDeserializationCodeForNestedSet(Context context) { TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0); String nestedSetCodec = context.makeName("nestedSetCodec"); + if (typeParameter instanceof TypeVariable) { + typeParameter = ((TypeVariable) typeParameter).getUpperBound(); + } context.builder.addStatement( "$T<$T> $L = new $T<>()", NestedSetCodec.class, @@ -953,6 +986,31 @@ class Marshallers { } }; + private final Marshaller charsetMarshaller = + new Marshaller() { + @Override + public boolean matches(DeclaredType type) { + return matchesType(type, Charset.class); + } + + @Override + public void addSerializationCode(Context context) { + context.builder.addStatement( + "$T.asciiOptimized().serialize(context, $L.name(), codedOut)", + StringCodecs.class, + context.name); + } + + @Override + public void addDeserializationCode(Context context) { + context.builder.addStatement( + "$L = $T.forName($T.asciiOptimized().deserialize(context, codedIn))", + context.name, + Charset.class, + StringCodecs.class); + } + }; + private final ImmutableList<PrimitiveValueSerializationCodeGenerator> primitiveGenerators = ImmutableList.of( INT_CODE_GENERATOR, @@ -982,6 +1040,7 @@ class Marshallers { hashCodeMarshaller, protoMarshaller, iterableMarshaller, + charsetMarshaller, contextMarshaller); /** True when {@code type} has the same type as {@code clazz}. */ diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java index 94690393ab..0cf644bd6e 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java @@ -67,6 +67,14 @@ interface SerializationCodeGenerator { return (DeclaredType) type; } + boolean isDeclaredType() { + return type instanceof DeclaredType; + } + + TypeMirror getTypeMirror() { + return type; + } + /** Returns true if this Context represents a type that can be null */ boolean canBeNull() { return !(type instanceof PrimitiveType); |