diff options
Diffstat (limited to 'java/com/google/devtools/build/android/desugar/DependencyCollector.java')
-rw-r--r-- | java/com/google/devtools/build/android/desugar/DependencyCollector.java | 98 |
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; + } + } +} |