summaryrefslogtreecommitdiff
path: root/java/com/google/devtools/build/android/desugar/DependencyCollector.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/devtools/build/android/desugar/DependencyCollector.java')
-rw-r--r--java/com/google/devtools/build/android/desugar/DependencyCollector.java98
1 files changed, 98 insertions, 0 deletions
diff --git a/java/com/google/devtools/build/android/desugar/DependencyCollector.java b/java/com/google/devtools/build/android/desugar/DependencyCollector.java
new file mode 100644
index 0000000..272a273
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/DependencyCollector.java
@@ -0,0 +1,98 @@
+// Copyright 2017 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.android.desugar;
+
+import javax.annotation.Nullable;
+
+/**
+ * Interface for collecting desugaring metadata that we can use to double-check correct desugaring
+ * at the binary level by looking at the metadata written for all Jars on the runtime classpath
+ * (b/65645388). Use {@link NoWriteCollectors} for "no-op" collectors and {@link
+ * com.google.devtools.build.android.desugar.dependencies.MetadataCollector} for writing out
+ * metadata files.
+ */
+// TODO(kmb): There could conceivably be a "self-contained" version where we check at the end that
+// we actually saw all the companion classes (in recordDefaultMethods) that we "assumed"; useful
+// for one-shot runs over an entire binary.
+@SuppressWarnings("unused") // default implementations consist of empty method stubs
+public interface DependencyCollector {
+
+ /** Class name suffix used for interface companion classes. */
+ public String INTERFACE_COMPANION_SUFFIX = "$$CC";
+
+ /**
+ * Records that {@code origin} depends on companion class {@code target}. For the resulting
+ * binary to be valid, {@code target} needs to exist, which isn't the case if the corresponding
+ * interface is only available as a compile-time ("neverlink") dependency.
+ */
+ default void assumeCompanionClass(String origin, String target) {}
+
+ /**
+ * Records that {@code origin} transitively implements {@code target} but {@code target} isn't
+ * in the classpath. This can lead to wrong desugarings if {@code target} or an interface it
+ * extends defines default methods.
+ */
+ default void missingImplementedInterface(String origin, String target) {}
+
+ /**
+ * Records that the given interface extends the given interfaces.
+ *
+ * <p>This information is useful reference to double-check {@link #missingImplementedInterface}s
+ * without reading and parsing .class files, specifically if default methods are defined in
+ * interfaces that a missing interface transitively extends.
+ */
+ default void recordExtendedInterfaces(String origin, String... targets) {}
+
+ /**
+ * Records that the given interface has a companion class that includes the given number of
+ * default methods (0 if there were only static methods). This method should not be called for
+ * purely abstract interfaces, to allow verifying available companion classes against this.
+ *
+ * <p>This information is useful reference to double-check {@link #missingImplementedInterface}s
+ * without reading and parsing .class files with better precision than just looking for
+ * companion classes on the runtime classpath (which may only contain static methods).
+ */
+ default void recordDefaultMethods(String origin, int count) {}
+
+ /**
+ * Returns metadata to include into the desugaring output or {@code null} if none. Returning
+ * anything but {@code null} will cause an extra file to be written into the output, including
+ * an empty array.
+ */
+ @Nullable public byte[] toByteArray();
+
+ /** Simple collectors that don't collect any information. */
+ public enum NoWriteCollectors implements DependencyCollector {
+ /** Singleton instance that does nothing. */
+ NOOP,
+ /**
+ * Singleton instance that does nothing besides throwing if {@link #missingImplementedInterface}
+ * is called.
+ */
+ FAIL_ON_MISSING {
+ @Override
+ public void missingImplementedInterface(String origin, String target) {
+ throw new IllegalStateException(
+ String.format(
+ "Couldn't find interface %s on the classpath for desugaring %s", target, origin));
+ }
+ };
+
+ @Override
+ @Nullable
+ public final byte[] toByteArray() {
+ return null;
+ }
+ }
+}