aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java37
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java65
-rw-r--r--src/test/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodecTest.java30
-rw-r--r--src/test/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodecTest.java37
6 files changed, 188 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java
index 52d316259e..93fe96e32e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java
@@ -26,6 +26,7 @@ import com.google.devtools.build.lib.packages.Attribute.AbstractLabelLateBoundDe
import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
@@ -47,6 +48,7 @@ import javax.annotation.concurrent.Immutable;
* target configuration.
*/
@Immutable
+@AutoCodec
public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDefault<FragmentT>
implements SkylarkValue {
@@ -82,13 +84,26 @@ public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDe
private SkylarkLateBoundDefault(SkylarkConfigurationField annotation,
Class<FragmentT> fragmentClass, String fragmentName, Method method, String toolsRepository) {
- super(false /* don't use host configuration */,
+ this(
+ getDefaultLabel(annotation, toolsRepository),
fragmentClass,
- getDefaultLabel(annotation, toolsRepository));
+ method,
+ fragmentName,
+ annotation.name());
+ }
+ @AutoCodec.VisibleForSerialization
+ @AutoCodec.Instantiator
+ SkylarkLateBoundDefault(
+ Label defaultVal,
+ Class<FragmentT> fragmentClass,
+ Method method,
+ String fragmentName,
+ String fragmentFieldName) {
+ super(/*useHostConfiguration=*/ false, fragmentClass, defaultVal);
this.method = method;
this.fragmentName = fragmentName;
- this.fragmentFieldName = annotation.name();
+ this.fragmentFieldName = fragmentFieldName;
}
/**
@@ -111,6 +126,12 @@ public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDe
printer.format("<late-bound default>");
}
+ /** For use by @AutoCodec since the {@link #defaultValue} field is hard for it to process. */
+ @AutoCodec.VisibleForSerialization
+ Label getDefaultVal() {
+ return getDefault();
+ }
+
/**
* An exception thrown if a user specifies an invalid configuration field identifier.
*
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
index ba1962335b..565e4f1290 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
@@ -30,7 +30,7 @@ import java.util.ArrayList;
import java.util.List;
/** A Skyframe value representing a package. */
-@AutoCodec
+@AutoCodec(memoization = AutoCodec.Memoization.START_MEMOIZING)
@Immutable
@ThreadSafe
public class PackageValue implements NotComparableSkyValue {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java
index e3675ee9e8..d21f928354 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.skyframe.serialization;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableBiMap;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
@@ -29,17 +31,40 @@ class ClassCodec implements ObjectCodec<Class<?>> {
@Override
public void serialize(SerializationContext context, Class<?> obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
- context.serialize(obj.getName(), codedOut);
+ codedOut.writeBoolNoTag(obj.isPrimitive());
+ if (obj.isPrimitive()) {
+ codedOut.writeInt32NoTag(Preconditions.checkNotNull(PRIMITIVE_CLASS_INDEX_MAP.get(obj), obj));
+ } else {
+ context.serialize(obj.getName(), codedOut);
+ }
}
@Override
public Class<?> deserialize(DeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
- String className = context.deserialize(codedIn);
- try {
- return Class.forName(className);
- } catch (ClassNotFoundException e) {
- throw new SerializationException("Couldn't find class for " + className, e);
+ boolean isPrimitive = codedIn.readBool();
+ if (isPrimitive) {
+ return PRIMITIVE_CLASS_INDEX_MAP.inverse().get(codedIn.readInt32());
+ } else {
+ String className = context.deserialize(codedIn);
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw new SerializationException("Couldn't find class for " + className, e);
+ }
}
}
+
+ private static final ImmutableBiMap<Class<?>, Integer> PRIMITIVE_CLASS_INDEX_MAP =
+ ImmutableBiMap.<Class<?>, Integer>builder()
+ .put(byte.class, 1)
+ .put(short.class, 2)
+ .put(int.class, 3)
+ .put(long.class, 4)
+ .put(char.class, 5)
+ .put(float.class, 6)
+ .put(double.class, 7)
+ .put(boolean.class, 8)
+ .put(void.class, 9)
+ .build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java
new file mode 100644
index 0000000000..5fc68d5db4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java
@@ -0,0 +1,65 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe.serialization;
+
+import com.google.protobuf.CodedInputStream;
+import com.google.protobuf.CodedOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/** {@link ObjectCodec} for {@link Method}. */
+class MethodCodec implements ObjectCodec<Method> {
+ @Override
+ public Class<Method> getEncodedClass() {
+ return Method.class;
+ }
+
+ @Override
+ public void serialize(SerializationContext context, Method obj, CodedOutputStream codedOut)
+ throws SerializationException, IOException {
+ context.serialize(obj.getDeclaringClass(), codedOut);
+ context.serialize(obj.getName(), codedOut);
+ Class<?>[] parameterTypes = obj.getParameterTypes();
+ codedOut.writeInt32NoTag(parameterTypes.length);
+ for (Class<?> parameter : parameterTypes) {
+ context.serialize(parameter, codedOut);
+ }
+ }
+
+ @Override
+ public Method deserialize(DeserializationContext context, CodedInputStream codedIn)
+ throws SerializationException, IOException {
+ Class<?> clazz = context.deserialize(codedIn);
+ String name = context.deserialize(codedIn);
+
+ Class<?>[] parameters = new Class<?>[codedIn.readInt32()];
+ for (int i = 0; i < parameters.length; i++) {
+ parameters[i] = context.deserialize(codedIn);
+ }
+ try {
+ return clazz.getDeclaredMethod(name, parameters);
+ } catch (NoSuchMethodException e) {
+ throw new SerializationException(
+ "Couldn't get method "
+ + name
+ + " in "
+ + clazz
+ + " with parameters "
+ + Arrays.toString(parameters),
+ e);
+ }
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodecTest.java
new file mode 100644
index 0000000000..16a0d2df7e
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodecTest.java
@@ -0,0 +1,30 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe.serialization;
+
+import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link ClassCodec}. */
+@RunWith(JUnit4.class)
+public class ClassCodecTest {
+ @Test
+ public void smoke() throws Exception {
+ new SerializationTester(String.class, Object.class, Class.class, int.class, boolean.class)
+ .runTests();
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodecTest.java
new file mode 100644
index 0000000000..0874331042
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodecTest.java
@@ -0,0 +1,37 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.skyframe.serialization;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
+import java.lang.reflect.Method;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link MethodCodec}. */
+@RunWith(JUnit4.class)
+public class MethodCodecTest {
+ @Test
+ public void smoke() throws Exception {
+ new SerializationTester(
+ ImmutableList.<Method>builder()
+ .add(String.class.getMethods())
+ .add(List.class.getMethods())
+ .build())
+ .runTests();
+ }
+}