aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java60
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/actions/ParameterFileWriteAction.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java83
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java8
5 files changed, 153 insertions, 35 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
index 1f3ef8770a..e90f856709 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
@@ -32,6 +32,8 @@ import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.LazyString;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -51,6 +53,7 @@ import javax.annotation.Nullable;
/** A customizable, serializable class for building memory efficient command lines. */
@Immutable
+@AutoCodec
public final class CustomCommandLine extends CommandLine {
private interface ArgvFragment {
@@ -151,6 +154,7 @@ public final class CustomCommandLine extends CommandLine {
* -> ["1:2:3"]
* </pre>
*/
+ @AutoCodec
public static class VectorArg<T> {
final boolean isNestedSet;
final boolean isEmpty;
@@ -159,7 +163,9 @@ public final class CustomCommandLine extends CommandLine {
final String beforeEach;
final String joinWith;
- private VectorArg(
+ @AutoCodec.Instantiator
+ @VisibleForSerialization
+ VectorArg(
boolean isNestedSet,
boolean isEmpty,
int count,
@@ -180,28 +186,43 @@ public final class CustomCommandLine extends CommandLine {
* <p>Call {@link SimpleVectorArg#mapped} to produce a vector arg that maps from a given type to
* a string.
*/
+ @AutoCodec
public static class SimpleVectorArg<T> extends VectorArg<T> {
private final Iterable<T> values;
private SimpleVectorArg(Builder builder, @Nullable Collection<T> values) {
- super(
+ this(
false /* isNestedSet */,
values == null || values.isEmpty(),
values != null ? values.size() : 0,
builder.formatEach,
builder.beforeEach,
- builder.joinWith);
- this.values = values;
+ builder.joinWith,
+ values);
}
private SimpleVectorArg(Builder builder, @Nullable NestedSet<T> values) {
- super(
+ this(
true /* isNestedSet */,
values == null || values.isEmpty(),
-1 /* count */,
builder.formatEach,
builder.beforeEach,
- builder.joinWith);
+ builder.joinWith,
+ values);
+ }
+
+ @AutoCodec.Instantiator
+ @VisibleForSerialization
+ SimpleVectorArg(
+ boolean isNestedSet,
+ boolean isEmpty,
+ int count,
+ String formatEach,
+ String beforeEach,
+ String joinWith,
+ @Nullable Iterable<T> values) {
+ super(isNestedSet, isEmpty, count, formatEach, beforeEach, joinWith);
this.values = values;
}
@@ -331,7 +352,8 @@ public final class CustomCommandLine extends CommandLine {
}
}
- private static final class VectorArgFragment implements ArgvFragment {
+ @AutoCodec
+ static final class VectorArgFragment implements ArgvFragment {
private static Interner<VectorArgFragment> interner = BlazeInterners.newStrongInterner();
private static final UUID FORMAT_EACH_UUID =
UUID.fromString("f830781f-2e0d-4e3b-9b99-ece7f249e0f3");
@@ -346,7 +368,9 @@ public final class CustomCommandLine extends CommandLine {
private final boolean hasBeforeEach;
private final boolean hasJoinWith;
- private VectorArgFragment(
+ @AutoCodec.Instantiator
+ @VisibleForSerialization
+ VectorArgFragment(
boolean isNestedSet,
boolean hasMapEach,
boolean hasFormatEach,
@@ -607,12 +631,14 @@ public final class CustomCommandLine extends CommandLine {
}
}
- private static final class ExpandedTreeArtifactExecPathsArg
- extends TreeArtifactExpansionArgvFragment {
+ @AutoCodec
+ static final class ExpandedTreeArtifactExecPathsArg extends TreeArtifactExpansionArgvFragment {
private final Artifact treeArtifact;
private static final UUID TREE_UUID = UUID.fromString("13b7626b-c77d-4a30-ad56-ff08c06b1cee");
- private ExpandedTreeArtifactExecPathsArg(Artifact treeArtifact) {
+ @AutoCodec.Instantiator
+ @VisibleForSerialization
+ ExpandedTreeArtifactExecPathsArg(Artifact treeArtifact) {
Preconditions.checkArgument(
treeArtifact.isTreeArtifact(), "%s is not a TreeArtifact", treeArtifact);
this.treeArtifact = treeArtifact;
@@ -1129,7 +1155,7 @@ public final class CustomCommandLine extends CommandLine {
builder.arguments.addAll(other.arguments);
return builder;
}
-
+
private final ImmutableList<Object> arguments;
/**
@@ -1142,14 +1168,14 @@ public final class CustomCommandLine extends CommandLine {
private final Map<Artifact, TreeFileArtifact> substitutionMap;
private CustomCommandLine(List<Object> arguments) {
- this.arguments = ImmutableList.copyOf(arguments);
- this.substitutionMap = null;
+ this(arguments, null);
}
- private CustomCommandLine(
- List<Object> arguments, Map<Artifact, TreeFileArtifact> substitutionMap) {
+ @AutoCodec.Instantiator
+ @VisibleForSerialization
+ CustomCommandLine(List<Object> arguments, Map<Artifact, TreeFileArtifact> substitutionMap) {
this.arguments = ImmutableList.copyOf(arguments);
- this.substitutionMap = ImmutableMap.copyOf(substitutionMap);
+ this.substitutionMap = substitutionMap == null ? null : ImmutableMap.copyOf(substitutionMap);
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ParameterFileWriteAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ParameterFileWriteAction.java
index caeab2ca5a..03b2084064 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/ParameterFileWriteAction.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/ParameterFileWriteAction.java
@@ -29,6 +29,8 @@ import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.actions.UserExecException;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.ShellEscaper;
import java.io.IOException;
@@ -36,10 +38,9 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
-/**
- * Action to write a parameter file for a {@link CommandLine}.
- */
+/** Action to write a parameter file for a {@link CommandLine}. */
@Immutable // if commandLine and charset are immutable
+@AutoCodec
public final class ParameterFileWriteAction extends AbstractFileWriteAction {
private static final String GUID = "45f678d8-e395-401e-8446-e795ccc6361f";
@@ -74,6 +75,7 @@ public final class ParameterFileWriteAction extends AbstractFileWriteAction {
* @param type the type of the file
* @param charset the charset of the file
*/
+ @AutoCodec.Instantiator
public ParameterFileWriteAction(
ActionOwner owner,
Iterable<Artifact> inputs,
@@ -81,7 +83,7 @@ public final class ParameterFileWriteAction extends AbstractFileWriteAction {
CommandLine commandLine,
ParameterFileType type,
Charset charset) {
- super(owner, ImmutableList.copyOf(inputs), output, false);
+ super(owner, inputs, output, false);
this.commandLine = commandLine;
this.type = type;
this.charset = charset;
@@ -121,6 +123,11 @@ public final class ParameterFileWriteAction extends AbstractFileWriteAction {
return new ParamFileWriter(arguments);
}
+ @VisibleForSerialization
+ Artifact getOutput() {
+ return Iterables.getOnlyElement(outputs);
+ }
+
private class ParamFileWriter implements DeterministicWriter {
private final Iterable<String> arguments;
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);