Clean Classic Desugar Source Code - Production - 1 / 2
#cleanup
- Main `java_binary` targets and its dependencies.
PiperOrigin-RevId: 468403617
Change-Id: Ib4222bda09d15a3eeb17ee40e914964d4d6ca56b
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/BUILD b/src/tools/android/java/com/google/devtools/build/android/desugar/BUILD
index 659278a..dc624fc 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/BUILD
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/BUILD
@@ -1,8 +1,6 @@
# Description:
# Tool for desugaring Java constructs not supported by Android tools or devices.
-load("@rules_java//java:defs.bzl", "java_binary", "java_library")
-
filegroup(
name = "embedded_tools",
srcs = ["BUILD.tools"],
@@ -13,64 +11,17 @@
java_library(
name = "desugar",
- srcs = glob(["*.java"]),
visibility = [
"//src/test/java/com/google/devtools/build/android/desugar:__pkg__",
"//src/tools/android/java/com/google/devtools/build/android:__pkg__",
"//src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit:__pkg__",
],
- runtime_deps = [
- "//src/tools/android/java/com/google/devtools/build/android/desugar/dependencies",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/runtime:primitives",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/runtime:string_concats",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/runtime:throwable_extension",
- ],
- deps = [
- "//src/main/java/com/google/devtools/common/options",
- "//src/main/protobuf:worker_protocol_java_proto",
- "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/config",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/corelibadapter",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/covariantreturn",
+ exports = [
"//src/tools/android/java/com/google/devtools/build/android/desugar/io",
"//src/tools/android/java/com/google/devtools/build/android/desugar/langmodel",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/nest",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/preanalysis",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/retarget",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/retarget:retarget_java_proto",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/strconcat",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/typeannotation",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/typehierarchy",
- "//src/tools/android/java/com/google/devtools/build/android/r8:deps_collector_api",
- "//third_party:asm",
- "//third_party:asm-commons",
- "//third_party:asm-tree",
- "//third_party:auto_value",
- "//third_party:flogger",
- "//third_party:guava",
- "//third_party:jsr305",
],
)
-sh_binary(
- name = "Desugar",
- srcs = ["desugar.sh"],
- data = [":Desugar_java"],
- visibility = [
- "//src/test/java/com/google/devtools/build/android/desugar:__pkg__",
- ],
- deps = ["@bazel_tools//tools/bash/runfiles"],
-)
-
-java_binary(
- name = "Desugar_java",
- main_class = "com.google.devtools.build.android.desugar.Desugar",
- visibility = [
- "//src/test/java/com/google/devtools/build/android/desugar:__pkg__",
- ],
- runtime_deps = [":desugar"],
-)
-
filegroup(
name = "srcs",
srcs = glob(["**"]) + [
@@ -88,7 +39,6 @@
"//src/tools/android/java/com/google/devtools/build/android/desugar/strconcat:srcs",
"//src/tools/android/java/com/google/devtools/build/android/desugar/preanalysis:srcs",
"//src/tools/android/java/com/google/devtools/build/android/desugar/scan:srcs",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit:srcs",
],
visibility = ["//src/tools/android/java/com/google/devtools/build/android:__pkg__"],
)
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/AsmNode.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/AsmNode.java
deleted file mode 100644
index e76ecbc..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/AsmNode.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.inject.Qualifier;
-import org.objectweb.asm.tree.ClassNode;
-
-/**
- * Identifies injectable ASM node fields (e.g. {@link org.objectweb.asm.tree.ClassNode}, {@link
- * org.objectweb.asm.tree.MethodNode}, {@link org.objectweb.asm.tree.FieldNode}) with a qualified
- * class name. The desugar rule resolves the requested class at runtime, parse it into a {@link
- * ClassNode} and assign parsed class node to the annotated field. An injectable ASM node field may
- * have any access modifier (private, package-private, protected, public). Sample usage:
- *
- * <pre><code>
- * @RunWith(JUnit4.class)
- * public class DesugarRuleTest {
- *
- * @Rule
- * public final DesugarRule desugarRule =
- * DesugarRule.builder(this, MethodHandles.lookup())
- * .addRuntimeInputs("path/to/my_jar.jar")
- * .build();
- *
- * @Inject
- * @AsmNode(className = "my.package.ClassToDesugar")
- * private ClassNode classToDesugarClassFile;
- *
- * // ... Test methods ...
- * }
- * </code></pre>
- */
-@Qualifier
-@Documented
-@Target({ElementType.FIELD, ElementType.PARAMETER})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface AsmNode {
-
- /**
- * The fully-qualified class name of the class to load. The format agrees with {@link
- * Class#getName}.
- */
- String className();
-
- /** If non-empty, load the specified class member (field or method) from the enclosing class. */
- String memberName() default "";
-
- /** If non-empty, use the specified member descriptor to disambiguate overloaded methods. */
- String memberDescriptor() default "";
-
- /** The round during which its associated jar is being used. */
- int round() default 1;
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/BUILD b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/BUILD
deleted file mode 100644
index f5dca05..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/BUILD
+++ /dev/null
@@ -1,50 +0,0 @@
-load("@rules_java//java:defs.bzl", "java_library")
-
-package(
- default_visibility = [
- "//src/test/java/com/google/devtools/build/android/desugar:__subpackages__",
- "//src/tools/android/java/com/google/devtools/build/android/desugar:__subpackages__",
- ],
-)
-
-java_library(
- name = "desugar_rule",
- srcs = glob(["*.java"]),
- deps = [
- "//src/tools/android/java/com/google/devtools/build/android/desugar",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/io",
- "//src/tools/android/java/com/google/devtools/build/android/desugar/langmodel",
- "//third_party:asm",
- "//third_party:asm-commons",
- "//third_party:asm-tree",
- "//third_party:auto_value",
- "//third_party:flogger",
- "//third_party:guava",
- "//third_party:jsr305",
- "//third_party:jsr330_inject",
- "//third_party:junit4",
- ],
-)
-
-filegroup(
- name = "android_jar_for_testing",
- srcs = select({
- # TODO(ajmichael): Use @bazel_tools//tools/android:android_jar here once it supplies runfiles.
- "//external:has_androidsdk": ["@androidsdk//:platforms/android-24/android.jar"],
- "//conditions:default": ["@bazel_tools//tools/android:error_message.jar"],
- }),
-)
-
-genrule(
- name = "jacoco_agent_jar",
- srcs = ["//third_party/java/jacoco:blaze-agent"],
- outs = ["jacoco_agent.jar"],
- cmd = """
- cp $(location //third_party/java/jacoco:blaze-agent) $(OUTS)
- """,
-)
-
-filegroup(
- name = "srcs",
- srcs = glob(["**"]),
-)
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRule.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRule.java
deleted file mode 100644
index 975aa01..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRule.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2019 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.testing.junit;
-
-import com.google.auto.value.AutoAnnotation;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.android.desugar.testing.junit.SourceCompilationUnit.SourceCompilationException;
-import java.io.IOException;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/** A JUnit4 Rule that desugars an input jar file and load the transformed jar to JVM. */
-public final class DesugarRule implements TestRule {
-
- static final ClassLoader BASE_CLASS_LOADER = ClassLoader.getSystemClassLoader().getParent();
-
- private final Object testInstance;
- private final MethodHandles.Lookup testInstanceLookup;
-
- private final ImmutableList<Field> injectableFields;
- private final ImmutableList<SourceCompilationUnit> sourceCompilationUnits;
- private final RuntimeEntityResolver runtimeEntityResolver;
-
- /**
- * The entry point to create a {@link DesugarRule}.
- *
- * @param testInstance The <code>this</code> reference of the JUnit test class.
- * @param testInstanceLookup The lookup object from the test class, i.e.<code>
- * MethodHandles.lookup()</code>
- */
- public static DesugarRuleBuilder builder(Object testInstance, Lookup testInstanceLookup) {
- return new DesugarRuleBuilder(testInstance, testInstanceLookup);
- }
-
- DesugarRule(
- Object testInstance,
- Lookup testInstanceLookup,
- ImmutableList<Field> injectableFields,
- ImmutableList<SourceCompilationUnit> sourceCompilationUnits,
- RuntimeEntityResolver runtimeEntityResolver) {
- this.testInstance = testInstance;
- this.testInstanceLookup = testInstanceLookup;
- this.injectableFields = injectableFields;
- this.sourceCompilationUnits = sourceCompilationUnits;
- this.runtimeEntityResolver = runtimeEntityResolver;
- }
-
- void compileSourceInputs() throws IOException, SourceCompilationException {
- for (SourceCompilationUnit compilationUnit : sourceCompilationUnits) {
- compilationUnit.compile();
- }
- }
-
- void executeDesugarTransformation() throws Exception {
- runtimeEntityResolver.executeTransformation();
- }
-
- @Override
- public Statement apply(Statement base, Description description) {
- return base;
- }
-
- public void injectTestInstanceFields() throws Throwable {
- for (Field field : injectableFields) {
- MethodHandle fieldSetter = testInstanceLookup.unreflectSetter(field);
- fieldSetter.invoke(testInstance, resolve(field, field.getType()));
- }
- }
-
- ImmutableMap<Parameter, Object> getResolvableParameters(Method method) throws Throwable {
- ImmutableMap.Builder<Parameter, Object> resolvableParameterValues = ImmutableMap.builder();
- for (Parameter parameter : method.getParameters()) {
- if (RuntimeEntityResolver.SUPPORTED_QUALIFIERS.stream()
- .anyMatch(parameter::isAnnotationPresent)) {
- resolvableParameterValues.put(parameter, resolve(parameter, parameter.getType()));
- }
- }
- return resolvableParameterValues.build();
- }
-
- public <T> T resolve(AnnotatedElement param, Class<T> type) throws Throwable {
- return runtimeEntityResolver.resolve(param, type);
- }
-
- ImmutableMap<String, Integer> getInputClassFileMajorVersionMap() {
- try {
- return runtimeEntityResolver.getInputClassFileMajorVersions();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @AutoAnnotation
- static DynamicClassLiteral createDynamicClassLiteral(String value, int round) {
- return new AutoAnnotation_DesugarRule_createDynamicClassLiteral(value, round);
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRuleBuilder.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRuleBuilder.java
deleted file mode 100644
index 39ca7f1..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRuleBuilder.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.jar.JarEntry;
-import javax.inject.Inject;
-import javax.tools.ToolProvider;
-import org.junit.runner.RunWith;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodNode;
-
-/** The builder class for {@link DesugarRule}. */
-public class DesugarRuleBuilder {
-
- private static final ImmutableSet<Class<?>> SUPPORTED_ASM_NODE_TYPES =
- ImmutableSet.of(ClassNode.class, FieldNode.class, MethodNode.class);
-
- private static final String ANDROID_RUNTIME_JAR_JVM_FLAG_KEY = "android_runtime_jar";
- private static final String JACOCO_AGENT_JAR_JVM_FLAG_KEY = "jacoco_agent_jar";
- private static final String DUMP_PROXY_CLASSES_JVM_FLAG_KEY =
- "jdk.internal.lambda.dumpProxyClasses";
-
- private final Object testInstance;
- private final MethodHandles.Lookup testInstanceLookup;
- private final ImmutableList<Field> injectableClassLiterals;
- private final ImmutableList<Field> injectableAsmNodes;
- private final ImmutableList<Field> injectableMethodHandles;
- private final ImmutableList<Field> injectableJarEntries;
- private String workingJavaPackage = "";
- private int maxNumOfTransformations = 1;
- private final List<Path> inputs = new ArrayList<>();
- private final List<Path> sourceInputs = new ArrayList<>();
- private final List<String> javacOptions = new ArrayList<>();
- private final List<Path> classPathEntries = new ArrayList<>();
- private final List<Path> bootClassPathEntries = new ArrayList<>();
- private final Multimap<String, String> customCommandOptions = LinkedHashMultimap.create();
- private final ErrorMessenger errorMessenger = new ErrorMessenger();
-
- private final String androidRuntimeJarJvmFlagValue;
- private final String jacocoAgentJarJvmFlagValue;
-
- DesugarRuleBuilder(Object testInstance, MethodHandles.Lookup testInstanceLookup) {
- this.testInstance = testInstance;
- this.testInstanceLookup = testInstanceLookup;
- Class<?> testClass = testInstance.getClass();
-
- androidRuntimeJarJvmFlagValue = getExplicitJvmFlagValue(ANDROID_RUNTIME_JAR_JVM_FLAG_KEY);
- jacocoAgentJarJvmFlagValue = getExplicitJvmFlagValue(JACOCO_AGENT_JAR_JVM_FLAG_KEY);
-
- if (testClass != testInstanceLookup.lookupClass()) {
- errorMessenger.addError(
- "Expected testInstanceLookup has private access to (%s), but get (%s). Have you"
- + " passed MethodHandles.lookup() to testInstanceLookup in test class?",
- testClass, testInstanceLookup.lookupClass());
- }
- if (!testClass.isAnnotationPresent(RunWith.class)) {
- errorMessenger.addError(
- "Expected a test instance whose class is annotated with @RunWith. %s", testClass);
- }
-
- injectableClassLiterals =
- findAllInjectableFieldsWithQualifier(testClass, DynamicClassLiteral.class);
- injectableAsmNodes = findAllInjectableFieldsWithQualifier(testClass, AsmNode.class);
- injectableMethodHandles =
- findAllInjectableFieldsWithQualifier(testClass, RuntimeMethodHandle.class);
- injectableJarEntries = findAllInjectableFieldsWithQualifier(testClass, RuntimeJarEntry.class);
- }
-
- static ImmutableList<Field> findAllInjectableFieldsWithQualifier(
- Class<?> testClass, Class<? extends Annotation> annotationClass) {
- ImmutableList.Builder<Field> fields = ImmutableList.builder();
- for (Class<?> currentClass = testClass;
- currentClass != null;
- currentClass = currentClass.getSuperclass()) {
- for (Field field : currentClass.getDeclaredFields()) {
- if (field.isAnnotationPresent(Inject.class) && field.isAnnotationPresent(annotationClass)) {
- fields.add(field);
- }
- }
- }
- return fields.build();
- }
-
- @CanIgnoreReturnValue
- public DesugarRuleBuilder setWorkingJavaPackage(String workingJavaPackage) {
- this.workingJavaPackage = workingJavaPackage;
- return this;
- }
-
- @CanIgnoreReturnValue
- public DesugarRuleBuilder enableIterativeTransformation(int maxNumOfTransformations) {
- this.maxNumOfTransformations = maxNumOfTransformations;
- return this;
- }
-
- @CanIgnoreReturnValue
- public DesugarRuleBuilder addInputs(Path... inputJars) {
- for (Path path : inputJars) {
- if (!path.toString().endsWith(".jar")) {
- errorMessenger.addError("Expected a JAR file (*.jar): Actual (%s)", path);
- }
- if (!Files.exists(path)) {
- errorMessenger.addError("File does not exist: %s", path);
- }
- inputs.add(path);
- }
- return this;
- }
-
- /** Add Java source files subject to be compiled during test execution. */
- @CanIgnoreReturnValue
- public DesugarRuleBuilder addSourceInputs(Path... inputSourceFiles) {
- for (Path path : inputSourceFiles) {
- if (!path.toString().endsWith(".java")) {
- errorMessenger.addError("Expected a Java source file (*.java): Actual (%s)", path);
- }
- if (!Files.exists(path)) {
- errorMessenger.addError("File does not exist: %s", path);
- }
- sourceInputs.add(path);
- }
- return this;
- }
-
- /**
- * Add JVM-flag-specified Java source files subject to be compiled during test execution. It is
- * expected the value associated with `jvmFlagKey` to be a space-separated Strings. E.g. on the
- * command line you would set it like: -Dinput_srcs="path1 path2 path3", and use <code>
- * .addSourceInputsFromJvmFlag("input_srcs").</code> in your test class.
- */
- public DesugarRuleBuilder addSourceInputsFromJvmFlag(String jvmFlagKey) {
- return addSourceInputs(DesugarTestHelpers.getRuntimePathsFromJvmFlag(jvmFlagKey));
- }
-
- /**
- * Add JVM-flag-specified Java source files subject to be compiled during test execution. It is
- * expected the value associated with `jvmFlagKey` to be a space-separated Strings. E.g. on the
- * command line you would set it like: -Dinput_srcs="path1 path2 path3", and use <code>
- * .addSourceInputsFromJvmFlag("input_srcs").</code> in your test class.
- */
- public DesugarRuleBuilder addJarInputsFromJvmFlag(String jvmFlagKey) {
- return addInputs(DesugarTestHelpers.getRuntimePathsFromJvmFlag(jvmFlagKey));
- }
-
- /**
- * Add javac options used for compilation, with the same support of `javacopts` attribute in
- * java_binary rule.
- */
- @CanIgnoreReturnValue
- public DesugarRuleBuilder addJavacOptions(String... javacOptions) {
- for (String javacOption : javacOptions) {
- if (!javacOption.startsWith("-")) {
- errorMessenger.addError(
- "Expected javac options, e.g. `-source 11`, `-target 11`, `-parameters`, Run `javac"
- + " -help` from terminal for all supported options.");
- }
- this.javacOptions.add(javacOption);
- }
- return this;
- }
-
- @CanIgnoreReturnValue
- public DesugarRuleBuilder addClasspathEntries(Path... inputJars) {
- Collections.addAll(classPathEntries, inputJars);
- return this;
- }
-
- @CanIgnoreReturnValue
- public DesugarRuleBuilder addBootClassPathEntries(Path... inputJars) {
- Collections.addAll(bootClassPathEntries, inputJars);
- return this;
- }
-
- /** Format: --<key>=<value> */
- @CanIgnoreReturnValue
- public DesugarRuleBuilder addCommandOptions(String key, String value) {
- customCommandOptions.put(key, value);
- return this;
- }
-
- private void checkJVMOptions() {
- if (Strings.isNullOrEmpty(getExplicitJvmFlagValue(DUMP_PROXY_CLASSES_JVM_FLAG_KEY))) {
- errorMessenger.addError(
- "Expected JVM flag: \"-D%s=$$(mktemp -d)\", but it is absent.",
- DUMP_PROXY_CLASSES_JVM_FLAG_KEY);
- }
-
- if (Strings.isNullOrEmpty(androidRuntimeJarJvmFlagValue)
- || !androidRuntimeJarJvmFlagValue.endsWith(".jar")
- || !Files.exists(Paths.get(androidRuntimeJarJvmFlagValue))) {
- errorMessenger.addError(
- "Android Runtime Jar does not exist: Please check JVM flag: -D%s='%s'",
- ANDROID_RUNTIME_JAR_JVM_FLAG_KEY, androidRuntimeJarJvmFlagValue);
- }
-
- if (Strings.isNullOrEmpty(jacocoAgentJarJvmFlagValue)
- || !jacocoAgentJarJvmFlagValue.endsWith(".jar")
- || !Files.exists(Paths.get(jacocoAgentJarJvmFlagValue))) {
- errorMessenger.addError(
- "Jacoco Agent Jar does not exist: Please check JVM flag: -D%s='%s'",
- JACOCO_AGENT_JAR_JVM_FLAG_KEY, jacocoAgentJarJvmFlagValue);
- }
- }
-
- public DesugarRule build() {
- checkInjectableClassLiterals();
- checkInjectableAsmNodes();
- checkInjectableMethodHandles();
- checkInjectableJarEntries();
-
- if (maxNumOfTransformations > 0) {
- checkJVMOptions();
- if (bootClassPathEntries.isEmpty()
- && !customCommandOptions.containsKey("allow_empty_bootclasspath")) {
- addBootClassPathEntries(Paths.get(androidRuntimeJarJvmFlagValue));
- }
- addClasspathEntries(Paths.get(jacocoAgentJarJvmFlagValue));
- }
-
- ImmutableList.Builder<SourceCompilationUnit> sourceCompilationUnits = ImmutableList.builder();
- if (!sourceInputs.isEmpty()) {
- try {
- Path runtimeCompiledJar = Files.createTempFile("runtime_compiled_", ".jar");
- sourceCompilationUnits.add(
- new SourceCompilationUnit(
- ToolProvider.getSystemJavaCompiler(),
- ImmutableList.copyOf(javacOptions),
- ImmutableList.copyOf(sourceInputs),
- runtimeCompiledJar));
- addInputs(runtimeCompiledJar);
- } catch (IOException e) {
- errorMessenger.addError(
- "Failed to access the output jar location for compilation: %s\n%s", sourceInputs, e);
- }
- }
-
- RuntimeEntityResolver runtimeEntityResolver =
- new RuntimeEntityResolver(
- testInstanceLookup,
- workingJavaPackage,
- maxNumOfTransformations,
- ImmutableList.copyOf(inputs),
- ImmutableList.copyOf(classPathEntries),
- ImmutableList.copyOf(bootClassPathEntries),
- ImmutableListMultimap.copyOf(customCommandOptions));
-
- if (errorMessenger.containsAnyError()) {
- throw new IllegalStateException(
- String.format(
- "Invalid Desugar configurations:\n%s\n",
- String.join("\n", errorMessenger.getAllMessages())));
- }
-
- return new DesugarRule(
- testInstance,
- testInstanceLookup,
- ImmutableList.<Field>builder()
- .addAll(injectableClassLiterals)
- .addAll(injectableAsmNodes)
- .addAll(injectableMethodHandles)
- .addAll(injectableJarEntries)
- .build(),
- sourceCompilationUnits.build(),
- runtimeEntityResolver);
- }
-
- private void checkInjectableClassLiterals() {
- for (Field field : injectableClassLiterals) {
- if (Modifier.isStatic(field.getModifiers())) {
- errorMessenger.addError("Expected to be non-static for field (%s)", field);
- }
-
- if (field.getType() != Class.class) {
- errorMessenger.addError("Expected a class literal type (Class<?>) for field (%s)", field);
- }
-
- DynamicClassLiteral dynamicClassLiteralAnnotation =
- field.getDeclaredAnnotation(DynamicClassLiteral.class);
- int round = dynamicClassLiteralAnnotation.round();
- if (round < 0 || round > maxNumOfTransformations) {
- errorMessenger.addError(
- "Expected the round (Actual:%d) of desugar transformation within [0, %d], where 0"
- + " indicates no transformation is applied.",
- round, maxNumOfTransformations);
- }
- }
- }
-
- private void checkInjectableAsmNodes() {
- for (Field field : injectableAsmNodes) {
- if (Modifier.isStatic(field.getModifiers())) {
- errorMessenger.addError("Expected to be non-static for field (%s)", field);
- }
-
- if (!SUPPORTED_ASM_NODE_TYPES.contains(field.getType())) {
- errorMessenger.addError(
- "Expected @inject @AsmNode on a field in one of: (%s) but gets (%s)",
- SUPPORTED_ASM_NODE_TYPES, field);
- }
-
- AsmNode astAsmNodeInfo = field.getDeclaredAnnotation(AsmNode.class);
- int round = astAsmNodeInfo.round();
- if (round < 0 || round > maxNumOfTransformations) {
- errorMessenger.addError(
- "Expected the round (actual:%d) of desugar transformation within [0, %d], where 0"
- + " indicates no transformation is used.",
- round, maxNumOfTransformations);
- }
- }
- }
-
- private void checkInjectableMethodHandles() {
- for (Field field : injectableMethodHandles) {
- if (Modifier.isStatic(field.getModifiers())) {
- errorMessenger.addError("Expected to be non-static for field (%s)", field);
- }
-
- if (field.getType() != MethodHandle.class) {
- errorMessenger.addError(
- "Expected @Inject @RuntimeMethodHandle annotated on a field with type (%s), but gets"
- + " (%s)",
- MethodHandle.class, field);
- }
-
- RuntimeMethodHandle methodHandleRequest =
- field.getDeclaredAnnotation(RuntimeMethodHandle.class);
- int round = methodHandleRequest.round();
- if (round < 0 || round > maxNumOfTransformations) {
- errorMessenger.addError(
- "Expected the round (actual:%d) of desugar transformation within [0, %d], where 0"
- + " indicates no transformation is used.",
- round, maxNumOfTransformations);
- }
- }
- }
-
- private void checkInjectableJarEntries() {
- for (Field field : injectableJarEntries) {
- if (Modifier.isStatic(field.getModifiers())) {
- errorMessenger.addError("Expected to be non-static for field (%s)", field);
- }
-
- if (field.getType() != JarEntry.class) {
- errorMessenger.addError(
- "Expected a field with Type: (%s) but gets (%s)", JarEntry.class.getName(), field);
- }
-
- RuntimeJarEntry jarEntryInfo = field.getDeclaredAnnotation(RuntimeJarEntry.class);
- if (jarEntryInfo.round() < 0 || jarEntryInfo.round() > maxNumOfTransformations) {
- errorMessenger.addError(
- "Expected the round of desugar transformation within [0, %d], where 0 indicates no"
- + " transformation is used.",
- maxNumOfTransformations);
- }
- }
- }
-
- private static String getExplicitJvmFlagValue(String jvmFlagKey) {
- String jvmFlagValue = System.getProperty(jvmFlagKey);
- return Strings.isNullOrEmpty(jvmFlagValue) ? "" : jvmFlagValue;
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRunner.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRunner.java
deleted file mode 100644
index aef4a80..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarRunner.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import static java.util.Collections.max;
-import static java.util.Collections.min;
-
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.flogger.GoogleLogger;
-import com.google.devtools.build.android.desugar.testing.junit.SourceCompilationUnit.SourceCompilationException;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-
-/**
- * A custom test runner that powers desugar tests.
- *
- * <p>The test runner works the same way as {@link org.junit.runners.JUnit4}, except that,
- * <li>Allows each {@link Test} method to declare injectable parameters, whose values will be
- * populated at runtime through {@link DesugarRule}.
- * <li>Performs a precondition check against {@link JdkSuppress} annotation if present. A test
- * passes vacuously without execution, if the precondition check fails.
- */
-public final class DesugarRunner extends BlockJUnit4ClassRunner {
-
- private static final int JAVA_RUNTIME_VERSION = JdkVersion.getJavaRuntimeVersion();
-
- private static final ImmutableSet<Class<? extends Annotation>> SUPPORTED_ANNOTATIONS =
- ImmutableSet.<Class<? extends Annotation>>builder()
- .addAll(RuntimeEntityResolver.SUPPORTED_QUALIFIERS)
- .add(FromParameterValueSource.class)
- .build();
-
- public DesugarRunner(Class<?> testClassLiteral) throws InitializationError {
- super(testClassLiteral);
- }
-
- @Override
- protected void validateTestMethods(List<Throwable> errors) {
- validatePublicVoidMethodsWithInjectableArgs(Test.class, /* isStatic= */ false, errors);
- }
-
- @Override
- protected boolean isIgnored(FrameworkMethod child) {
- return isJdkSuppressed(child) || super.isIgnored(child);
- }
-
- private boolean isJdkSuppressed(FrameworkMethod child) {
- JdkSuppress jdkSuppress = getJdkSuppress(child);
- return jdkSuppress != null
- && (JAVA_RUNTIME_VERSION < jdkSuppress.minJdkVersion()
- || JAVA_RUNTIME_VERSION > jdkSuppress.maxJdkVersion());
- }
-
- private JdkSuppress getJdkSuppress(FrameworkMethod child) {
- JdkSuppress jdkSuppress = child.getAnnotation(JdkSuppress.class);
- return jdkSuppress != null ? jdkSuppress : getTestClass().getAnnotation(JdkSuppress.class);
- }
-
- @Override
- protected List<FrameworkMethod> computeTestMethods() {
- List<FrameworkMethod> frameworkMethods = super.computeTestMethods();
- // Generates one method for each @ParameterValueSource instance.
- ImmutableList.Builder<FrameworkMethod> expandedFrameworkMethods = ImmutableList.builder();
- for (FrameworkMethod frameworkMethod : frameworkMethods) {
- Method reflectMethod = frameworkMethod.getMethod();
- if (reflectMethod.isAnnotationPresent(ParameterValueSourceSet.class)) {
- ParameterValueSourceSet paramValues =
- reflectMethod.getDeclaredAnnotation(ParameterValueSourceSet.class);
- for (ParameterValueSource paramValueBundle : paramValues.value()) {
- expandedFrameworkMethods.add(
- ValueSourceAnnotatedMethod.create(frameworkMethod.getMethod(), paramValueBundle));
- }
- } else if (reflectMethod.isAnnotationPresent(ParameterValueSource.class)) {
- ParameterValueSource paramValueBundle =
- reflectMethod.getDeclaredAnnotation(ParameterValueSource.class);
- expandedFrameworkMethods.add(
- ValueSourceAnnotatedMethod.create(frameworkMethod.getMethod(), paramValueBundle));
- } else {
- expandedFrameworkMethods.add(frameworkMethod);
- }
- }
- return expandedFrameworkMethods.build();
- }
-
- /**
- * In replacement of {@link BlockJUnit4ClassRunner#validatePublicVoidNoArgMethods} for @Test
- * method signature validation.
- */
- private void validatePublicVoidMethodsWithInjectableArgs(
- Class<? extends Annotation> annotation, boolean isStatic, List<Throwable> errors) {
- List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(annotation);
- for (FrameworkMethod eachTestMethod : methods) {
- eachTestMethod.validatePublicVoid(isStatic, errors);
- validateInjectableParameters(eachTestMethod, errors);
- validateParameterValueSource(eachTestMethod, errors);
- }
- }
-
- private static void validateInjectableParameters(
- FrameworkMethod eachTestMethod, List<Throwable> errors) {
- for (Parameter parameter : eachTestMethod.getMethod().getParameters()) {
- if (Arrays.stream(parameter.getDeclaredAnnotations())
- .map(Annotation::annotationType)
- .noneMatch(SUPPORTED_ANNOTATIONS::contains)) {
- errors.add(
- new Exception(
- String.format(
- "Expected the parameter (%s) in @Test method (%s) annotated with one of"
- + " the supported qualifiers %s to be injectable.",
- parameter, eachTestMethod, SUPPORTED_ANNOTATIONS)));
- }
- }
- }
-
- private static void validateParameterValueSource(
- FrameworkMethod eachTestMethod, List<Throwable> errors) {
- Method reflectMethod = eachTestMethod.getMethod();
- long numOfParamsWithValueRequest =
- Arrays.stream(reflectMethod.getParameters())
- .filter(parameter -> parameter.isAnnotationPresent(FromParameterValueSource.class))
- .count();
- if (numOfParamsWithValueRequest > 0) {
- List<ParameterValueSource> parameterValueSources = new ArrayList<>();
- if (reflectMethod.isAnnotationPresent(ParameterValueSource.class)) {
- parameterValueSources.add(reflectMethod.getDeclaredAnnotation(ParameterValueSource.class));
- }
- if (reflectMethod.isAnnotationPresent(ParameterValueSourceSet.class)) {
- Collections.addAll(
- parameterValueSources,
- reflectMethod.getDeclaredAnnotation(ParameterValueSourceSet.class).value());
- }
- for (ParameterValueSource parameterValueSource : parameterValueSources) {
- int valueSourceLength = parameterValueSource.value().length;
- if (valueSourceLength != numOfParamsWithValueRequest) {
- errors.add(
- new Exception(
- String.format(
- "Parameter value source bundle (%s) and @FromParameterValueSource-annotated"
- + " parameters in Method (%s) mismatch in length.",
- parameterValueSource, eachTestMethod)));
- }
- }
- }
- }
-
- @Override
- protected Statement methodInvoker(FrameworkMethod method, Object test) {
- DesugarRule desugarRule =
- Iterables.getOnlyElement(
- getTestClass().getAnnotatedFieldValues(test, Rule.class, DesugarRule.class));
-
- // Compile source Java files before desugar transformation.
- try {
- desugarRule.compileSourceInputs();
- } catch (IOException | SourceCompilationException e) {
- throw new IllegalStateException(e);
- }
-
- JdkSuppress jdkSuppress = getJdkSuppress(method);
- if (jdkSuppress != null) {
- ImmutableMap<String, Integer> inputClassFileMajorVersions =
- desugarRule.getInputClassFileMajorVersionMap();
- ImmutableCollection<Integer> classFileVersions = inputClassFileMajorVersions.values();
- if (min(classFileVersions) < jdkSuppress.minJdkVersion()
- || max(classFileVersions) > jdkSuppress.maxJdkVersion()) {
- return new VacuousSuccess(
- String.format(
- "@Test method (%s) passed vacuously without execution: All or part of the input"
- + " class file versions (%s) does not meet the declared prerequisite version"
- + " range (%s) for testing.",
- method, inputClassFileMajorVersions, jdkSuppress));
- }
- }
-
- try {
- desugarRule.executeDesugarTransformation();
- desugarRule.injectTestInstanceFields();
- Method reflectMethod = method.getMethod();
-
- ImmutableMap.Builder<Parameter, Object> parameterBindingsBuilder = ImmutableMap.builder();
- // Load bindings from annotations.
- if (reflectMethod.isAnnotationPresent(ParameterValueSourceSet.class)
- || reflectMethod.isAnnotationPresent(ParameterValueSource.class)) {
- parameterBindingsBuilder.putAll(
- ((ValueSourceAnnotatedMethod) method).getResolvableParameters());
- }
- // Load bindings from desugar rule.
- parameterBindingsBuilder.putAll(desugarRule.getResolvableParameters(reflectMethod));
-
- ImmutableMap<Parameter, Object> parameterBindings = parameterBindingsBuilder.build();
- Parameter[] parameters = reflectMethod.getParameters();
- int parameterCount = parameters.length;
- Object[] resolvedParameterValues = new Object[parameterCount];
- for (int i = 0; i < parameterCount; i++) {
- resolvedParameterValues[i] = parameterBindings.get(parameters[i]);
- }
- return new InvokeMethodWithParams(method, test, resolvedParameterValues);
- } catch (Throwable throwable) {
- throw new IllegalStateException(throwable);
- }
- }
-
- /**
- * Used as in replacement of {@link org.junit.internal.runners.statements.InvokeMethod} for @Test
- * method execution.
- */
- static class InvokeMethodWithParams extends Statement {
- private final FrameworkMethod testMethod;
- private final Object target;
- private final Object[] params;
-
- InvokeMethodWithParams(FrameworkMethod testMethod, Object target, Object... params) {
- this.testMethod = testMethod;
- this.target = target;
- this.params = params;
- }
-
- @Override
- public void evaluate() throws Throwable {
- testMethod.invokeExplosively(target, params);
- }
- }
-
- /**
- * Used as a statement implementation indicating that a test will pass without the execution of
- * test method body.
- */
- static final class VacuousSuccess extends Statement {
-
- private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
-
- private final String reason;
-
- VacuousSuccess(String reason) {
- this.reason = reason;
- }
-
- @Override
- public void evaluate() throws Throwable {
- logger.atWarning().log("%s", reason);
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + ":" + reason;
- }
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarTestHelpers.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarTestHelpers.java
deleted file mode 100644
index cd69fa4..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DesugarTestHelpers.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableList.toImmutableList;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.android.desugar.langmodel.ClassName;
-import com.google.devtools.build.android.desugar.langmodel.MemberUseKind;
-import com.google.devtools.build.android.desugar.langmodel.MethodInvocationSite;
-import com.google.devtools.build.android.desugar.langmodel.MethodKey;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.function.Predicate;
-import java.util.regex.Pattern;
-import org.objectweb.asm.tree.AbstractInsnNode;
-import org.objectweb.asm.tree.MethodInsnNode;
-import org.objectweb.asm.tree.MethodNode;
-
-/** Static utilities that facilities desugar testing. */
-public class DesugarTestHelpers {
-
- private DesugarTestHelpers() {}
-
- /**
- * A helper method that reads file paths into an array from the JVM flag value associated with
- * {@code jvmFlagKey}.
- */
- public static Path[] getRuntimePathsFromJvmFlag(String jvmFlagKey) {
- String jvmPropertyValue =
- checkNotNull(
- System.getProperty(jvmFlagKey),
- "Expected JVM Option to be specified: -D<%s>=<YourValue>",
- jvmFlagKey);
- return Splitter.on(" ").trimResults().splitToList(jvmPropertyValue).stream()
- .map(Paths::get)
- .toArray(Path[]::new);
- }
-
- /** Find all matched method invocation instructions in the given method. */
- public static ImmutableList<MethodInvocationSite> findMethodInvocationSites(
- MethodNode enclosingMethod,
- String methodOwnerRegex,
- String methodNameRegex,
- String methodDescRegex) {
- Predicate<String> methodOwnerPredicate = Pattern.compile(methodOwnerRegex).asPredicate();
- Predicate<String> methodNamePredicate = Pattern.compile(methodNameRegex).asPredicate();
- Predicate<String> methodDescPredicate = Pattern.compile(methodDescRegex).asPredicate();
- return filterInstructions(enclosingMethod, AbstractInsnNode.METHOD_INSN).stream()
- .map(node -> (MethodInsnNode) node)
- .filter(node -> methodOwnerPredicate.test(node.owner))
- .filter(node -> methodNamePredicate.test(node.name))
- .filter(node -> methodDescPredicate.test(node.desc))
- .map(
- node ->
- MethodInvocationSite.builder()
- .setInvocationKind(MemberUseKind.fromValue(node.getOpcode()))
- .setMethod(MethodKey.create(ClassName.create(node.owner), node.name, node.desc))
- .setIsInterface(node.itf)
- .build())
- .collect(toImmutableList());
- }
-
- public static ImmutableList<AbstractInsnNode> filterInstructions(
- MethodNode enclosingMethod, int instructionType) {
- return Arrays.stream(enclosingMethod.instructions.toArray())
- .filter(node -> node.getType() == instructionType)
- .collect(toImmutableList());
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DynamicClassLiteral.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DynamicClassLiteral.java
deleted file mode 100644
index 6ff14a4..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/DynamicClassLiteral.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2019 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.inject.Qualifier;
-
-/**
- * Identifies injectable class-literal fields with the specified class to load at runtime and assign
- * to the field. An injectable class-literal field may have any access modifier (private,
- * package-private, protected, public). Sample usage:
- *
- * <pre><code>
- * @RunWith(JUnit4.class)
- * public class DesugarRuleTest {
- *
- * @Rule
- * public final DesugarRule desugarRule =
- * DesugarRule.builder(this, MethodHandles.lookup())
- * .addRuntimeInputs("path/to/my_jar.jar")
- * .build();
- * @Inject
- * @DynamicClassLiteral("my.package.ClassToDesugar")
- * private Class<?> classToDesugarClass;
- *
- * // ... Test methods ...
- * }
- * </code></pre>
- */
-@Qualifier
-@Documented
-@Target({ElementType.FIELD, ElementType.PARAMETER})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface DynamicClassLiteral {
-
- /**
- * The fully-qualified class name of the class to load. The format agrees with {@link
- * Class#getName}.
- */
- String value();
-
- /** The round during which its associated jar is being used. */
- int round() default 1;
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ErrorMessenger.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ErrorMessenger.java
deleted file mode 100644
index f5d19b1..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ErrorMessenger.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.FormatMethod;
-import java.util.ArrayList;
-import java.util.List;
-
-/** A messenger that manages desugar configuration errors. */
-class ErrorMessenger {
-
- private final List<String> errorMessages = new ArrayList<>();
-
- @CanIgnoreReturnValue
- @FormatMethod
- ErrorMessenger addError(String recipe, Object... args) {
- errorMessages.add(String.format(recipe, args));
- return this;
- }
-
- boolean containsAnyError() {
- return !errorMessages.isEmpty();
- }
-
- List<String> getAllMessages() {
- return errorMessages;
- }
-
- @Override
- public String toString() {
- return getAllMessages().toString();
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/FromParameterValueSource.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/FromParameterValueSource.java
deleted file mode 100644
index c5e3e1b..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/FromParameterValueSource.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marks a method parameter whose value will be derived from {@link ParameterValueSource}.
- *
- * @see ParameterValueSource for code examples.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.PARAMETER)
-public @interface FromParameterValueSource {}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JarTransformationRecord.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JarTransformationRecord.java
deleted file mode 100644
index 0a15d83..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JarTransformationRecord.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2019 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.testing.junit;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.Iterables;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-
-/** The transformation record that describes the desugaring of a jar. */
-@AutoValue
-abstract class JarTransformationRecord {
-
- /**
- * The full runtime path of a pre-transformationRecord jar.
- *
- * @see com.google.devtools.build.android.desugar.config.DesugarOptions#inputJars for details.
- */
- abstract ImmutableList<Path> inputJars();
-
- /**
- * The full runtime path of a post-transformationRecord jar (deguared jar).
- *
- * @see com.google.devtools.build.android.desugar.config.DesugarOptions#inputJars for details.
- */
- abstract ImmutableList<Path> outputJars();
-
- /** @see com.google.devtools.build.android.desugar.config.DesugarOptions#classpath for details. */
- abstract ImmutableList<Path> classPathEntries();
-
- /**
- * @see com.google.devtools.build.android.desugar.config.DesugarOptions#bootclasspath for details.
- */
- abstract ImmutableList<Path> bootClassPathEntries();
-
- /** The remaining command options used for desugaring. */
- abstract ImmutableListMultimap<String, String> extraCustomCommandOptions();
-
- /** The factory method of this jar transformation record. */
- static JarTransformationRecord create(
- ImmutableList<Path> inputJars,
- ImmutableList<Path> outputJars,
- ImmutableList<Path> classPathEntries,
- ImmutableList<Path> bootClassPathEntries,
- ImmutableListMultimap<String, String> extraCustomCommandOptions) {
- return new AutoValue_JarTransformationRecord(
- inputJars, outputJars, classPathEntries, bootClassPathEntries, extraCustomCommandOptions);
- }
-
- final ImmutableList<String> getDesugarFlags() {
- ImmutableList.Builder<String> args = ImmutableList.builder();
- inputJars().forEach(path -> args.add("--input=" + path));
- outputJars().forEach(path -> args.add("--output=" + path));
- classPathEntries().forEach(path -> args.add("--classpath_entry=" + path));
- bootClassPathEntries().forEach(path -> args.add("--bootclasspath_entry=" + path));
- extraCustomCommandOptions().forEach((k, v) -> args.add("--" + k + "=" + v));
- return args.build();
- }
-
- @Memoized
- ClassLoader getOutputClassLoader() throws MalformedURLException {
- List<URL> urls = new ArrayList<>();
- for (Path path : Iterables.concat(outputJars(), classPathEntries(), bootClassPathEntries())) {
- urls.add(path.toUri().toURL());
- }
- return URLClassLoader.newInstance(urls.toArray(new URL[0]), DesugarRule.BASE_CLASS_LOADER);
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JdkSuppress.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JdkSuppress.java
deleted file mode 100644
index dc21d8a..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JdkSuppress.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates that a specific test class or test method requires a minimum and/or maximum JDK version
- * to execute.
- *
- * <p>A test will be ignored (passed vacuously) if the actual JDK version under test is out of the
- * expected JDK version range. (inclusive). It is up to the implementer to specify the source of
- * truth of the JDK version under investigation, e.g. the Java runtime environment, source code
- * language level, class file major version, etc.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.METHOD})
-public @interface JdkSuppress {
- /** The minimum JDK version to execute (inclusive) */
- int minJdkVersion() default JdkVersion.V1_8;
- /** The maximum JDK version to execute (inclusive) */
- int maxJdkVersion() default Integer.MAX_VALUE;
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JdkVersion.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JdkVersion.java
deleted file mode 100644
index 329b94b..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/JdkVersion.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import com.google.common.base.Splitter;
-import java.util.List;
-
-/**
- * Enumeration of the currently known Java ClassFile versions.
- *
- * <p>The minor version is stored in the 16 most significant bits, and the major version in the 16
- * least significant bits. These are the values that can be found in
- * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.1-200-B.2
- */
-public final class JdkVersion {
- private static final Splitter SPLITTER_DOT = Splitter.on('.');
- private static final String JAVA_RUNTIME_VERSION_TEXT =
- System.getProperty("java.runtime.version");
-
- public static final int V1_1 = 3 << 16 | 45;
- public static final int V1_2 = 0 << 16 | 46;
- public static final int V1_3 = 0 << 16 | 47;
- public static final int V1_4 = 0 << 16 | 48;
- public static final int V1_5 = 0 << 16 | 49;
- public static final int V1_6 = 0 << 16 | 50;
- public static final int V1_7 = 0 << 16 | 51;
- public static final int V1_8 = 0 << 16 | 52;
- public static final int V9 = 0 << 16 | 53;
- public static final int V10 = 0 << 16 | 54;
- public static final int V11 = 0 << 16 | 55;
- public static final int V12 = 0 << 16 | 56;
- public static final int V13 = 0 << 16 | 57;
- public static final int V14 = 0 << 16 | 58;
-
- public static int getJavaRuntimeVersion() {
- if (JAVA_RUNTIME_VERSION_TEXT.startsWith("1.1.")) {
- return JdkVersion.V1_1;
- }
- List<String> versionSegments = SPLITTER_DOT.splitToList(JAVA_RUNTIME_VERSION_TEXT);
- if (JAVA_RUNTIME_VERSION_TEXT.startsWith("1.")) {
- return JdkVersion.V1_2 - 2 + Integer.parseInt(versionSegments.get(1));
- }
- return JdkVersion.V9 - 9 + Integer.parseInt(versionSegments.get(0));
- }
-
- private JdkVersion() {}
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ParameterValueSource.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ParameterValueSource.java
deleted file mode 100644
index 64767d6..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ParameterValueSource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Repeatable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * A bundle of textually-represented values, subject to parsing before populating parameters.
- *
- * <p>Code Example:
- *
- * <pre><code>
- * @Test
- * @ParameterValueSource({"1", "2", "3"})
- * @ParameterValueSource({"200", "300", "500"})
- * public void twoSum(
- * @FromParameterValueSource int operandLeft,
- * @FromParameterValueSource int operandRight,
- * @FromParameterValueSource int expectedResult) {
- * assertThat(operandLeft + operandRight).isEqualTo(expectedResult);
- * }
- * </code></pre>
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-@Repeatable(ParameterValueSourceSet.class)
-public @interface ParameterValueSource {
- String[] value();
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ParameterValueSourceSet.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ParameterValueSourceSet.java
deleted file mode 100644
index cac3217..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ParameterValueSourceSet.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** The container for the repeatable {@link ParameterValueSource} annotation. */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface ParameterValueSourceSet {
- ParameterValueSource[] value();
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeEntityResolver.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeEntityResolver.java
deleted file mode 100644
index ab4d81a..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeEntityResolver.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import static com.google.common.base.Preconditions.checkState;
-import static org.objectweb.asm.ClassReader.SKIP_CODE;
-import static org.objectweb.asm.ClassReader.SKIP_DEBUG;
-import static org.objectweb.asm.ClassReader.SKIP_FRAMES;
-
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Table;
-import com.google.devtools.build.android.desugar.Desugar;
-import com.google.devtools.build.android.desugar.io.JarItem;
-import com.google.devtools.build.android.desugar.langmodel.ClassMemberKey;
-import com.google.devtools.build.android.desugar.langmodel.ClassName;
-import com.google.devtools.build.android.desugar.langmodel.FieldKey;
-import com.google.devtools.build.android.desugar.langmodel.MethodKey;
-import com.google.devtools.build.android.desugar.testing.junit.RuntimeMethodHandle.MemberUseContext;
-import org.objectweb.asm.Opcodes;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodNode;
-
-/** Resolves the dependencies of fields and test method parameters under desugar testing. */
-final class RuntimeEntityResolver {
-
- static final ImmutableSet<Class<? extends Annotation>> SUPPORTED_QUALIFIERS =
- ImmutableSet.of(
- DynamicClassLiteral.class,
- AsmNode.class,
- RuntimeMethodHandle.class,
- RuntimeJarEntry.class);
- private static final String DEFAULT_OUTPUT_ROOT_PREFIX = "desugared_dump";
-
- private final MethodHandles.Lookup testInstanceLookup;
- private final String workingJavaPackage;
- private final int maxNumOfTransformations;
- private final ImmutableList<Path> inputs;
- private final ImmutableList<Path> classPathEntries;
- private final ImmutableList<Path> bootClassPathEntries;
- private final ImmutableMultimap<String, String> customCommandOptions;
-
- private final List<JarTransformationRecord> jarTransformationRecords;
- private ClassLoader inputClassLoader;
-
- /** The state of the already-created directories to avoid directory re-creation. */
- private final Map<String, Path> tempDirs = new HashMap<>();
-
- /** A table for the lookup of missing user-supplied class member descriptors. */
- private final Table<
- Integer, // Desugar round
- ClassMemberKey<?>, // A class member without descriptor (empty descriptor string).
- Set<ClassMemberKey<?>>> // The set of same-name class members with their descriptors.
- descriptorLookupRepo = HashBasedTable.create();
-
- /**
- * A table for the lookup of reflection-based class member representation from round and class
- * member key.
- */
- private final Table<
- Integer, // Desugar round
- ClassMemberKey<?>, // A class member with descriptor.
- java.lang.reflect.Member> // A reflection-based Member instance.
- reflectionBasedMembers = HashBasedTable.create();
-
- RuntimeEntityResolver(
- Lookup testInstanceLookup,
- String workingJavaPackage,
- int maxNumOfTransformations,
- ImmutableList<Path> inputs,
- ImmutableList<Path> classPathEntries,
- ImmutableList<Path> bootClassPathEntries,
- ImmutableMultimap<String, String> customCommandOptions) {
- this.testInstanceLookup = testInstanceLookup;
- this.workingJavaPackage = workingJavaPackage;
- this.maxNumOfTransformations = maxNumOfTransformations;
- this.inputs = inputs;
- this.classPathEntries = classPathEntries;
- this.bootClassPathEntries = bootClassPathEntries;
- this.customCommandOptions = customCommandOptions;
- this.jarTransformationRecords = new ArrayList<>(maxNumOfTransformations);
- }
-
- void executeTransformation() throws Exception {
- inputClassLoader = getInputClassLoader();
- ImmutableList<Path> transInputs = inputs;
- for (int round = 1; round <= maxNumOfTransformations; round++) {
- ImmutableList<Path> transOutputs =
- getRuntimeOutputPaths(
- transInputs,
- tempDirs,
- /* outputRootPrefix= */ DEFAULT_OUTPUT_ROOT_PREFIX + "_" + round);
- JarTransformationRecord transformationRecord =
- JarTransformationRecord.create(
- transInputs,
- transOutputs,
- ImmutableList.copyOf(classPathEntries),
- ImmutableList.copyOf(bootClassPathEntries),
- ImmutableListMultimap.copyOf(customCommandOptions));
- Desugar.main(transformationRecord.getDesugarFlags().toArray(new String[0]));
- jarTransformationRecords.add(transformationRecord);
- transInputs = transOutputs;
- }
- }
-
- public <T> T resolve(AnnotatedElement element, Class<T> elementType) throws Throwable {
- DynamicClassLiteral dynamicClassLiteralRequest =
- element.getDeclaredAnnotation(DynamicClassLiteral.class);
- if (dynamicClassLiteralRequest != null) {
- return elementType.cast(
- loadClassLiteral(
- dynamicClassLiteralRequest,
- jarTransformationRecords,
- inputClassLoader,
- reflectionBasedMembers,
- descriptorLookupRepo,
- workingJavaPackage));
- }
- AsmNode asmNodeRequest = element.getDeclaredAnnotation(AsmNode.class);
- if (asmNodeRequest != null) {
- return getAsmNode(
- asmNodeRequest, elementType, jarTransformationRecords, inputs, workingJavaPackage);
- }
- RuntimeMethodHandle runtimeMethodHandleRequest =
- element.getDeclaredAnnotation(RuntimeMethodHandle.class);
- if (runtimeMethodHandleRequest != null) {
- return elementType.cast(
- getMethodHandle(
- runtimeMethodHandleRequest,
- testInstanceLookup,
- jarTransformationRecords,
- inputClassLoader,
- reflectionBasedMembers,
- descriptorLookupRepo,
- workingJavaPackage));
- }
- RuntimeJarEntry runtimeJarEntry = element.getDeclaredAnnotation(RuntimeJarEntry.class);
- if (runtimeJarEntry != null) {
- return elementType.cast(
- getJarEntry(runtimeJarEntry, jarTransformationRecords, inputs, workingJavaPackage));
- }
- throw new UnsupportedOperationException(
- "Expected one of the supported types for injection: " + SUPPORTED_QUALIFIERS);
- }
-
- private static void fillMissingClassMemberDescriptorRepo(
- int round,
- Class<?> classLiteral,
- Table<Integer, ClassMemberKey<?>, Set<ClassMemberKey<?>>> missingDescriptorLookupRepo) {
- ClassName owner = ClassName.create(classLiteral);
- for (Constructor<?> constructor : classLiteral.getDeclaredConstructors()) {
- ClassMemberKey<?> memberKeyWithoutDescriptor = MethodKey.create(owner, "<init>", "");
- ClassMemberKey<?> memberKeyWithDescriptor =
- MethodKey.create(owner, "<init>", Type.getConstructorDescriptor(constructor));
- if (missingDescriptorLookupRepo.contains(round, memberKeyWithoutDescriptor)) {
- missingDescriptorLookupRepo
- .get(round, memberKeyWithoutDescriptor)
- .add(memberKeyWithDescriptor);
- } else {
- missingDescriptorLookupRepo.put(
- round, memberKeyWithoutDescriptor, Sets.newHashSet(memberKeyWithDescriptor));
- }
- }
- for (Method method : classLiteral.getDeclaredMethods()) {
- ClassMemberKey<?> memberKeyWithoutDescriptor = MethodKey.create(owner, method.getName(), "");
- ClassMemberKey<?> memberKeyWithDescriptor =
- MethodKey.create(owner, method.getName(), Type.getMethodDescriptor(method));
- if (missingDescriptorLookupRepo.contains(round, memberKeyWithoutDescriptor)) {
- missingDescriptorLookupRepo
- .get(round, memberKeyWithoutDescriptor)
- .add(memberKeyWithDescriptor);
- } else {
- missingDescriptorLookupRepo.put(
- round, memberKeyWithoutDescriptor, Sets.newHashSet(memberKeyWithDescriptor));
- }
- }
- for (Field field : classLiteral.getDeclaredFields()) {
- ClassMemberKey<?> memberKeyWithoutDescriptor = FieldKey.create(owner, field.getName(), "");
- ClassMemberKey<?> memberKeyWithDescriptor =
- FieldKey.create(owner, field.getName(), Type.getDescriptor(field.getType()));
- if (missingDescriptorLookupRepo.contains(round, memberKeyWithoutDescriptor)) {
- missingDescriptorLookupRepo
- .get(round, memberKeyWithoutDescriptor)
- .add(memberKeyWithDescriptor);
- } else {
- missingDescriptorLookupRepo.put(
- round, memberKeyWithoutDescriptor, Sets.newHashSet(memberKeyWithDescriptor));
- }
- }
- }
-
- private static ImmutableTable<Integer, ClassMemberKey<?>, Member> getReflectionBasedClassMembers(
- int round, Class<?> classLiteral) {
- ImmutableTable.Builder<Integer, ClassMemberKey<?>, Member> reflectionBasedMembers =
- ImmutableTable.builder();
- ClassName owner = ClassName.create(classLiteral);
- for (Field field : classLiteral.getDeclaredFields()) {
- reflectionBasedMembers.put(
- round,
- FieldKey.create(owner, field.getName(), Type.getDescriptor(field.getType())),
- field);
- }
- for (Constructor<?> constructor : classLiteral.getDeclaredConstructors()) {
- reflectionBasedMembers.put(
- round,
- MethodKey.create(owner, "<init>", Type.getConstructorDescriptor(constructor)),
- constructor);
- }
- for (Method method : classLiteral.getDeclaredMethods()) {
- reflectionBasedMembers.put(
- round,
- MethodKey.create(owner, method.getName(), Type.getMethodDescriptor(method)),
- method);
- }
- return reflectionBasedMembers.buildOrThrow();
- }
-
- private static Class<?> loadClassLiteral(
- DynamicClassLiteral dynamicClassLiteralRequest,
- List<JarTransformationRecord> jarTransformationRecords,
- ClassLoader initialInputClassLoader,
- Table<Integer, ClassMemberKey<?>, Member> reflectionBasedMembers,
- Table<Integer, ClassMemberKey<?>, Set<ClassMemberKey<?>>> missingDescriptorLookupRepo,
- String workingJavaPackage)
- throws Throwable {
- int round = dynamicClassLiteralRequest.round();
- ClassLoader outputJarClassLoader =
- round == 0
- ? initialInputClassLoader
- : jarTransformationRecords.get(round - 1).getOutputClassLoader();
- String requestedClassName = dynamicClassLiteralRequest.value();
- String qualifiedClassName =
- workingJavaPackage.isEmpty() || requestedClassName.contains(".")
- ? requestedClassName
- : workingJavaPackage + "." + requestedClassName;
- Class<?> classLiteral = outputJarClassLoader.loadClass(qualifiedClassName);
- reflectionBasedMembers.putAll(getReflectionBasedClassMembers(round, classLiteral));
- fillMissingClassMemberDescriptorRepo(round, classLiteral, missingDescriptorLookupRepo);
- return classLiteral;
- }
-
- private static <T> T getAsmNode(
- AsmNode asmNodeRequest,
- Class<T> requestedNodeType,
- List<JarTransformationRecord> jarTransformationRecords,
- ImmutableList<Path> initialInputs,
- String workingJavaPackage)
- throws IOException, ClassNotFoundException {
- String requestedClassName = asmNodeRequest.className();
- String qualifiedClassName =
- workingJavaPackage.isEmpty() || requestedClassName.contains(".")
- ? requestedClassName
- : workingJavaPackage + "." + requestedClassName;
- String classFileName = qualifiedClassName.replace('.', '/') + ".class";
- int round = asmNodeRequest.round();
- ImmutableList<Path> jars =
- round == 0 ? initialInputs : jarTransformationRecords.get(round - 1).outputJars();
- ClassNode classNode = findClassNode(classFileName, jars);
- if (requestedNodeType == ClassNode.class) {
- return requestedNodeType.cast(classNode);
- }
-
- String memberName = asmNodeRequest.memberName();
- String memberDescriptor = asmNodeRequest.memberDescriptor();
- if (requestedNodeType == FieldNode.class) {
- return requestedNodeType.cast(getFieldNode(classNode, memberName, memberDescriptor));
- }
- if (requestedNodeType == MethodNode.class) {
- return requestedNodeType.cast(getMethodNode(classNode, memberName, memberDescriptor));
- }
-
- throw new UnsupportedOperationException(
- String.format("Injecting a node type (%s) is not supported", requestedNodeType));
- }
-
- private static MethodHandle getMethodHandle(
- RuntimeMethodHandle methodHandleRequest,
- Lookup lookup,
- List<JarTransformationRecord> jarTransformationRecords,
- ClassLoader initialInputClassLoader,
- Table<Integer, ClassMemberKey<?>, java.lang.reflect.Member> reflectionBasedMembers,
- Table<Integer, ClassMemberKey<?>, Set<ClassMemberKey<?>>> missingDescriptorLookupRepo,
- String workingJavaPackage)
- throws Throwable {
- int round = methodHandleRequest.round();
- Class<?> classLiteral =
- loadClassLiteral(
- DesugarRule.createDynamicClassLiteral(methodHandleRequest.className(), round),
- jarTransformationRecords,
- initialInputClassLoader,
- reflectionBasedMembers,
- missingDescriptorLookupRepo,
- workingJavaPackage);
-
- ClassName owner = ClassName.create(classLiteral);
- String memberName = methodHandleRequest.memberName();
- String memberDescriptor = methodHandleRequest.memberDescriptor();
-
- ClassMemberKey<?> classMemberKey =
- methodHandleRequest.usage() == MemberUseContext.METHOD_INVOCATION
- ? MethodKey.create(owner, memberName, memberDescriptor)
- : FieldKey.create(owner, memberName, memberDescriptor);
-
- if (classMemberKey.descriptor().isEmpty()) {
- classMemberKey = restoreMissingDescriptor(classMemberKey, round, missingDescriptorLookupRepo);
- }
-
- switch (methodHandleRequest.usage()) {
- case METHOD_INVOCATION:
- return classMemberKey.isConstructor()
- ? lookup.unreflectConstructor(
- (Constructor<?>) reflectionBasedMembers.get(round, classMemberKey))
- : lookup.unreflect((Method) reflectionBasedMembers.get(round, classMemberKey));
- case FIELD_GETTER:
- return lookup.unreflectGetter((Field) reflectionBasedMembers.get(round, classMemberKey));
- case FIELD_SETTER:
- return lookup.unreflectSetter((Field) reflectionBasedMembers.get(round, classMemberKey));
- }
-
- throw new AssertionError(
- String.format(
- "Beyond exhaustive enum values: Unexpected enum value (%s) for (Enum:%s)",
- methodHandleRequest.usage(), MemberUseContext.class));
- }
-
- private static ClassMemberKey<?> restoreMissingDescriptor(
- ClassMemberKey<?> classMemberKey,
- int round,
- Table<Integer, ClassMemberKey<?>, Set<ClassMemberKey<?>>> missingDescriptorLookupRepo) {
- Set<ClassMemberKey<?>> restoredClassMemberKey =
- missingDescriptorLookupRepo.get(round, classMemberKey);
- if (restoredClassMemberKey == null || restoredClassMemberKey.isEmpty()) {
- throw new IllegalStateException(
- String.format(
- "Unable to find class member (%s). Please check its presence.", classMemberKey));
- } else if (restoredClassMemberKey.size() > 1) {
- throw new IllegalStateException(
- String.format(
- "Class Member (%s) has same-name overloaded members: (%s) \n"
- + "Please specify a descriptor to disambiguate overloaded method request.",
- classMemberKey, restoredClassMemberKey));
- }
- return Iterables.getOnlyElement(restoredClassMemberKey);
- }
-
- private static FieldNode getFieldNode(
- ClassNode classNode, String fieldName, String fieldDescriptor) {
- for (FieldNode field : classNode.fields) {
- if (fieldName.equals(field.name)) {
- checkState(
- fieldDescriptor.isEmpty() || fieldDescriptor.equals(field.desc),
- "Found name-matched field but with a different descriptor. Expected requested field"
- + " descriptor, if specified, agrees with the actual field type. Field name <%s>"
- + " in class <%s>; Requested Type <%s>; Actual Type: <%s>.",
- fieldName,
- classNode.name,
- fieldDescriptor,
- field.desc);
- return field;
- }
- }
- throw new IllegalStateException(
- String.format("Field <%s> not found in class <%s>", fieldName, classNode.name));
- }
-
- private static MethodNode getMethodNode(
- ClassNode classNode, String methodName, String methodDescriptor) {
- boolean hasMethodDescriptor = !methodDescriptor.isEmpty();
- List<MethodNode> matchedMethods =
- classNode.methods.stream()
- .filter(methodNode -> methodName.equals(methodNode.name))
- .filter(methodNode -> !hasMethodDescriptor || methodDescriptor.equals(methodNode.desc))
- .collect(Collectors.toList());
- if (matchedMethods.isEmpty()) {
- throw new IllegalStateException(
- String.format(
- "Method <name:%s%s> is not found in class <%s>",
- methodName,
- hasMethodDescriptor ? ", descriptor:" + methodDescriptor : "",
- classNode.name));
- }
- if (matchedMethods.size() > 1) {
- List<String> matchedMethodDescriptors =
- matchedMethods.stream().map(method -> method.desc).collect(Collectors.toList());
- throw new IllegalStateException(
- String.format(
- "Multiple matches for requested method (name: %s in class %s). Please specify the"
- + " method descriptor to disambiguate overloaded method request. All descriptors"
- + " of name-matched methods: %s.",
- methodName, classNode.name, matchedMethodDescriptors));
- }
- return Iterables.getOnlyElement(matchedMethods);
- }
-
- private static JarItem getJarEntry(
- RuntimeJarEntry jarEntryRequest,
- List<JarTransformationRecord> jarTransformationRecords,
- ImmutableList<Path> initialInputs,
- String workingJavaPackage)
- throws IOException {
- String requestedClassFile = jarEntryRequest.value();
- String jarEntryPathName =
- workingJavaPackage.isEmpty() || requestedClassFile.contains("/")
- ? requestedClassFile
- : workingJavaPackage.replace('.', '/') + '/' + requestedClassFile;
- int round = jarEntryRequest.round();
- ImmutableList<Path> jars =
- round == 0 ? initialInputs : jarTransformationRecords.get(round - 1).outputJars();
- for (Path jar : jars) {
- JarFile jarFile = new JarFile(jar.toFile());
- JarEntry jarEntry = jarFile.getJarEntry(jarEntryPathName);
- if (jarEntry != null) {
- return JarItem.create(jarFile, jarEntry);
- }
- }
- throw new IllegalStateException(
- String.format("Expected zip entry of (%s) present.", jarEntryPathName));
- }
-
- private static ClassNode findClassNode(String jarEntryPathName, ImmutableList<Path> jars)
- throws IOException, ClassNotFoundException {
- for (Path jar : jars) {
- JarFile jarFile = new JarFile(jar.toFile());
- JarEntry jarEntry = jarFile.getJarEntry(jarEntryPathName);
- if (jarEntry != null) {
- try (InputStream inputStream = jarFile.getInputStream(jarEntry)) {
- ClassReader cr = new ClassReader(inputStream);
- ClassNode classNode = new ClassNode(Opcodes.ASM9);
- cr.accept(classNode, 0);
- return classNode;
- }
- }
- }
- throw new ClassNotFoundException(jarEntryPathName);
- }
-
- private ClassLoader getInputClassLoader() throws MalformedURLException {
- List<URL> urls = new ArrayList<>();
- for (Path path : Iterables.concat(inputs, classPathEntries, bootClassPathEntries)) {
- urls.add(path.toUri().toURL());
- }
- return URLClassLoader.newInstance(urls.toArray(new URL[0]), DesugarRule.BASE_CLASS_LOADER);
- }
-
- private static ImmutableList<Path> getRuntimeOutputPaths(
- ImmutableList<Path> inputs, Map<String, Path> tempDirs, String outputRootPrefix)
- throws IOException {
- ImmutableList.Builder<Path> outputRuntimePathsBuilder = ImmutableList.builder();
- for (Path path : inputs) {
- String targetDirKey = Paths.get(outputRootPrefix) + "/" + path.getParent();
- final Path outputDirPath;
- if (tempDirs.containsKey(targetDirKey)) {
- outputDirPath = tempDirs.get(targetDirKey);
- } else {
- Path root = Files.createTempDirectory("junit");
- Files.delete(root);
- outputDirPath = Files.createDirectories(root.resolve(Paths.get(targetDirKey)));
- tempDirs.put(targetDirKey, outputDirPath);
- }
- outputRuntimePathsBuilder.add(outputDirPath.resolve(path.getFileName()));
- }
- return outputRuntimePathsBuilder.build();
- }
-
- ImmutableMap<String, Integer> getInputClassFileMajorVersions() throws IOException {
- return getInputClassFileMajorVersions(inputs);
- }
-
- private static ImmutableMap<String, Integer> getInputClassFileMajorVersions(Collection<Path> jars)
- throws IOException {
- ImmutableMap.Builder<String, Integer> majorVersions = ImmutableMap.builder();
- for (Path jar : jars) {
- JarFile jarFile = new JarFile(jar.toFile());
- List<JarEntry> classFileJarEntries =
- jarFile.stream()
- .filter(jarEntry -> jarEntry.getName().endsWith(".class"))
- .collect(Collectors.toList());
- for (JarEntry jarEntry : classFileJarEntries) {
- try (InputStream inputStream = jarFile.getInputStream(jarEntry)) {
- ClassReader cr = new ClassReader(inputStream);
- ClassNode classNode = new ClassNode(Opcodes.ASM9);
- cr.accept(classNode, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
- majorVersions.put(classNode.name, classNode.version);
- }
- }
- }
- return majorVersions.build();
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeJarEntry.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeJarEntry.java
deleted file mode 100644
index a5693de..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeJarEntry.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2019 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.testing.junit;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.inject.Qualifier;
-
-/**
- * Identifies injectable {@link com.google.devtools.build.android.desugar.io.JarItem} fields with a
- * zip entry path. The desugar rule resolves the requested zip entry at runtime and assign it to the
- * annotated field. An injectable {@link RuntimeJarEntry}-annotated field may have any access
- * modifier (private, package-private, protected, public). Sample usage:
- *
- * <pre><code>
- * @RunWith(JUnit4.class)
- * public class DesugarRuleTest {
- *
- * @Rule
- * public final DesugarRule desugarRule =
- * DesugarRule.builder(this, MethodHandles.lookup())
- * .addInputs(Paths.get("path/to/my_jar.jar"))
- * .build();
- *
- * @Inject
- * @RuntimeJarEntry("my/package/ClassToDesugar.class")
- * private JarItem classToDesugarClassFile;
- *
- * // ... Test methods ...
- * }
- * </code></pre>
- */
-@Qualifier
-@Documented
-@Target({ElementType.FIELD, ElementType.PARAMETER})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RuntimeJarEntry {
-
- /** The requested zip entry path name within a zip file. */
- String value();
-
- /** The round during which its associated jar is being used. */
- int round() default 1;
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeMethodHandle.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeMethodHandle.java
deleted file mode 100644
index 2a0ae27..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/RuntimeMethodHandle.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2019 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.testing.junit;
-
-import static com.google.devtools.build.android.desugar.testing.junit.RuntimeMethodHandle.MemberUseContext.METHOD_INVOCATION;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.inject.Qualifier;
-import org.objectweb.asm.tree.ClassNode;
-
-/**
- * Identifies injectable ASM node fields (e.g. {@link org.objectweb.asm.tree.ClassNode}, {@link
- * org.objectweb.asm.tree.MethodNode}, {@link org.objectweb.asm.tree.FieldNode}) with a qualified
- * class name. The desugar rule resolves the requested class at runtime, parses it into a {@link
- * ClassNode}, and assigns the parsed class node to the annotated field. An injectable ASM node
- * field may have any access modifier (private, package-private, protected, public). Sample usage:
- *
- * <pre><code>
- * @RunWith(JUnit4.class)
- * public class DesugarRuleTest {
- *
- * @Rule
- * public final DesugarRule desugarRule =
- * DesugarRule.builder(this, MethodHandles.lookup())
- * .addRuntimeInputs("path/to/my_jar.jar")
- * .build();
- *
- * @Inject
- * @RuntimeMethodHandle(
- * className = "my.package.ClassToDesugar",
- * memberName = "add",
- * memberDescriptor = "(II)I",
- * round = 2,
- * )
- * private MethodHandle adder;
- *
- * // ... Test methods ...
- * }
- * </code></pre>
- */
-@Qualifier
-@Documented
-@Target({ElementType.FIELD, ElementType.PARAMETER})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RuntimeMethodHandle {
-
- /**
- * The fully-qualified class name of the class to load. The format agrees with {@link
- * Class#getName}.
- */
- String className();
-
- /** If non-empty, load the specified class member (field or method) from the enclosing class. */
- String memberName() default "";
-
- /** If non-empty, use the specified member descriptor to disambiguate overloaded methods. */
- String memberDescriptor() default "";
-
- MemberUseContext usage() default METHOD_INVOCATION;
-
- /** The round during which its associated jar is being used. */
- int round() default 1;
-
- /** All class member use context types. */
- enum MemberUseContext {
- METHOD_INVOCATION,
- FIELD_GETTER,
- FIELD_SETTER,
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/SourceCompilationUnit.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/SourceCompilationUnit.java
deleted file mode 100644
index b166897..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/SourceCompilationUnit.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.ByteStreams;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.tools.JavaCompiler;
-
-/** Represents a compilation unit with a single jar output. */
-public final class SourceCompilationUnit {
-
- /** The java compiler used to compile source files. */
- private final JavaCompiler compiler;
-
- /**
- * customJavacOptions The javac options used for compilation, with the same support of `javacopts`
- * attribute in java_binary rule.
- */
- private final ImmutableList<String> customJavacOptions;
-
- /** The collection of source files subject to compile. */
- private final ImmutableList<Path> sourceInputs;
-
- /** The caller-specified write-permissible file path to the compiled jar. */
- private final Path outputJar;
-
- public SourceCompilationUnit(
- JavaCompiler compiler,
- ImmutableList<String> customJavacOptions,
- ImmutableList<Path> sourceInputs,
- Path outputJar) {
- this.compiler = compiler;
- this.customJavacOptions = customJavacOptions;
- this.sourceInputs = sourceInputs;
- this.outputJar = outputJar;
- }
-
- /** Compiles Java source files and write to the pre-specified path to the output jar. */
- Path compile() throws IOException, SourceCompilationException {
- Path compilationStdOut = Files.createTempFile("compilation_stdout_", ".txt");
- Path compilationStdErr = Files.createTempFile("compilation_stderr_", ".txt");
- Path compiledRootDir = Files.createTempDirectory("compilation_prodout_");
- ImmutableList<String> javacOptions =
- ImmutableList.<String>builder()
- .addAll(customJavacOptions)
- .add("-d " + compiledRootDir)
- .build();
- final List<Path> compiledFiles;
- try (OutputStream stdOutStream = Files.newOutputStream(compilationStdOut);
- OutputStream stdErrStream = Files.newOutputStream(compilationStdErr)) {
- Splitter splitter = Splitter.on(" ").trimResults().omitEmptyStrings();
- ImmutableList<String> compilationArguments =
- ImmutableList.<String>builder()
- .addAll(splitter.split(String.join(" ", javacOptions)))
- .addAll(sourceInputs.stream().map(Path::toString).collect(Collectors.toList()))
- .build();
- compiler.run(
- nullInputStream(),
- stdOutStream,
- stdErrStream,
- compilationArguments.toArray(new String[0]));
- int maxDepth = sourceInputs.stream().mapToInt(Path::getNameCount).max().getAsInt();
- try (Stream<Path> outputStream =
- Files.find(compiledRootDir, maxDepth, (path, fileAttr) -> true)) {
- compiledFiles = outputStream.collect(Collectors.toList());
- }
- try (JarOutputStream jarOutputStream =
- new JarOutputStream(Files.newOutputStream(outputJar))) {
- for (Path compiledFile : compiledFiles) {
- try (InputStream inputStream = Files.newInputStream(compiledFile)) {
- Path inArchivalPath = compiledRootDir.relativize(compiledFile);
- JarEntry jarEntry = new JarEntry(inArchivalPath.toString());
- jarOutputStream.putNextEntry(jarEntry);
- if (!Files.isDirectory(compiledFile)) {
- ByteStreams.copy(inputStream, jarOutputStream);
- }
- jarOutputStream.closeEntry();
- }
- }
- }
- }
- String compilationStandardErrorMessage =
- new String(Files.readAllBytes(compilationStdErr), Charset.defaultCharset());
- if (!compilationStandardErrorMessage.isEmpty()) {
- throw new SourceCompilationException(compilationStandardErrorMessage);
- }
- return outputJar;
- }
-
- private static InputStream nullInputStream() {
- return new ByteArrayInputStream(new byte[] {});
- }
-
- static class SourceCompilationException extends Exception {
- public SourceCompilationException(String message) {
- super(message);
- }
- }
-}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ValueSourceAnnotatedMethod.java b/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ValueSourceAnnotatedMethod.java
deleted file mode 100644
index 4b38a1a..0000000
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/testing/junit/ValueSourceAnnotatedMethod.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2020 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.testing.junit;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.collect.ImmutableMap;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
-import java.util.Arrays;
-import java.util.Objects;
-import org.junit.runners.model.FrameworkMethod;
-
-/**
- * Represents a {@link ParameterValueSource}-annotated method with its parameter values (either
- * fully or partially) derivable from the associated value source annotation. The test runner will
- * parameterize a @Test method with N {@link ParameterValueSource} annotations into N {@link
- * ValueSourceAnnotatedMethod}s for testing, and provides value bindings to all {@link
- * FromParameterValueSource}-annotated parameters from a {@link ParameterValueSource} instance in
- * sequence.
- */
-public final class ValueSourceAnnotatedMethod extends FrameworkMethod {
-
- /** One single bundle for parameter value resolution. */
- private final ParameterValueSource parameterValueSource;
-
- public static ValueSourceAnnotatedMethod create(
- Method method, ParameterValueSource parameterValueSource) {
- return new ValueSourceAnnotatedMethod(method, parameterValueSource);
- }
-
- private ValueSourceAnnotatedMethod(Method method, ParameterValueSource parameterValueSource) {
- super(method);
- this.parameterValueSource = parameterValueSource;
- }
-
- ImmutableMap<Parameter, Object> getResolvableParameters() {
- String[] providedParamValues = parameterValueSource.value();
- int i = 0;
- ImmutableMap.Builder<Parameter, Object> resolvableParameterValues = ImmutableMap.builder();
- for (Parameter parameter : getMethod().getParameters()) {
- if (parameter.isAnnotationPresent(FromParameterValueSource.class)) {
- resolvableParameterValues.put(
- parameter, parsePrimitive(providedParamValues[i++], parameter.getType()));
- }
- }
- return resolvableParameterValues.build();
- }
-
- @Override
- public String getName() {
- // Appends distinct suffixes to support test filters.
- return super.getName() + "_" + Arrays.toString(parameterValueSource.value());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj instanceof ValueSourceAnnotatedMethod) {
- ValueSourceAnnotatedMethod that = (ValueSourceAnnotatedMethod) obj;
- return this.parameterValueSource.equals(that.parameterValueSource)
- && this.getMethod().equals(that.getMethod());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getMethod(), parameterValueSource);
- }
-
- @Override
- public String toString() {
- return super.toString() + "_" + Arrays.toString(parameterValueSource.value());
- }
-
- private static Object parsePrimitive(String text, Class<?> targetType) {
- if (targetType == String.class) {
- return text;
- }
- if (targetType == int.class) {
- return Integer.parseInt(text);
- }
- if (targetType == boolean.class) {
- return Boolean.parseBoolean(text);
- }
- if (targetType == byte.class) {
- return Byte.parseByte(text);
- }
- if (targetType == char.class) {
- checkState(text.length() == 1, "Expected a single character for char type");
- return text.charAt(0);
- }
- if (targetType == short.class) {
- return Short.parseShort(text);
- }
- if (targetType == double.class) {
- return Double.parseDouble(text);
- }
- if (targetType == float.class) {
- return Float.parseFloat(text);
- }
- if (targetType == long.class) {
- return Long.parseLong(text);
- }
- throw new UnsupportedOperationException("Expected a primitive type: " + text);
- }
-}