aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar kmb <kmb@google.com>2018-03-12 21:37:51 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-03-12 21:40:00 -0700
commit2cbeb24a9c41c6b14ecbb26e2e198fbaf79aea64 (patch)
tree472a5fd3ad9a4ad69dac57376f4de4090ffc02e6
parent0084e16b55ad54f7aeeffd6d003ea3506039d957 (diff)
Make KeepScanner tool search classpath for nearest definition of each member reference, instead of potentially referring to a subtype.
Refactor desugar's class loading machinery and related code into a separate package for easier reuse in this tool. RELNOTES: None. PiperOrigin-RevId: 188825305
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/BUILD30
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java1
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/CorePackageRenamerTest.java1
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixerTest.java5
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/Java7CompatibilityTest.java1
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java1
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/io/BUILD53
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/io/FieldInfoTest.java (renamed from src/test/java/com/google/devtools/build/android/desugar/FieldInfoTest.java)2
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/io/IndexedInputsTest.java (renamed from src/test/java/com/google/devtools/build/android/desugar/IndexedInputsTest.java)2
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/scan/testdata/CollectionReferences.java4
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/scan/testdata_golden.txt16
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/BUILD2
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/BytecodeTypeInference.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java3
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/ClassVsInterface.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibrarySupport.java2
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java48
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/EmulatedInterfaceRewriter.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java2
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/Java7Compatibility.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassFixer.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/LambdaDesugaring.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/BUILD25
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/BitFlags.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/BitFlags.java)4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/CoreLibraryRewriter.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java)8
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/DirectoryInputFileProvider.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/DirectoryInputFileProvider.java)2
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/DirectoryOutputFileProvider.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/DirectoryOutputFileProvider.java)4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/FieldInfo.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/FieldInfo.java)4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/HeaderClassLoader.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java)4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/IndexedInputs.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/IndexedInputs.java)4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/InputFileProvider.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/InputFileProvider.java)17
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/OutputFileProvider.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/OutputFileProvider.java)17
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/ThrowingClassLoader.java27
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/ZipInputFileProvider.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/ZipInputFileProvider.java)2
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/io/ZipOutputFileProvider.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/ZipOutputFileProvider.java)4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/scan/KeepScanner.java143
40 files changed, 354 insertions, 94 deletions
diff --git a/src/test/java/com/google/devtools/build/android/desugar/BUILD b/src/test/java/com/google/devtools/build/android/desugar/BUILD
index 602a48e326..da56672a5c 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/BUILD
+++ b/src/test/java/com/google/devtools/build/android/desugar/BUILD
@@ -13,6 +13,7 @@ filegroup(
srcs = glob(["**"]) + [
"//src/test/java/com/google/devtools/build/android/desugar/classes_for_testing_type_inference:srcs",
"//src/test/java/com/google/devtools/build/android/desugar/dependencies:srcs",
+ "//src/test/java/com/google/devtools/build/android/desugar/io:srcs",
"//src/test/java/com/google/devtools/build/android/desugar/runtime:srcs",
],
visibility = ["//src/test/java/com/google/devtools/build/android:__pkg__"],
@@ -367,6 +368,7 @@ java_test(
deps = [
"//src/tools/android/java/com/google/devtools/build/android/desugar",
"//src/tools/android/java/com/google/devtools/build/android/desugar:deps_collector_api",
+ "//src/tools/android/java/com/google/devtools/build/android/desugar/io",
"//third_party:asm",
"//third_party:asm-tree",
"//third_party:guava",
@@ -388,22 +390,12 @@ java_test(
)
java_test(
- name = "FieldInfoTest",
- size = "small",
- srcs = ["FieldInfoTest.java"],
- deps = [
- "//src/tools/android/java/com/google/devtools/build/android/desugar",
- "//third_party:junit4",
- "//third_party:truth",
- ],
-)
-
-java_test(
name = "Java7CompatibilityTest",
size = "small",
srcs = ["Java7CompatibilityTest.java"],
deps = [
"//src/tools/android/java/com/google/devtools/build/android/desugar",
+ "//src/tools/android/java/com/google/devtools/build/android/desugar/io",
"//third_party:asm",
"//third_party:junit4",
"//third_party:truth",
@@ -411,18 +403,6 @@ java_test(
)
java_test(
- name = "IndexedInputsTest",
- size = "small",
- srcs = ["IndexedInputsTest.java"],
- deps = [
- "//src/tools/android/java/com/google/devtools/build/android/desugar",
- "//third_party:guava",
- "//third_party:junit4",
- "//third_party:truth",
- ],
-)
-
-java_test(
name = "TryWithResourcesRewriterUnitTestWithReuseStrategy",
size = "small",
srcs = [
@@ -439,6 +419,7 @@ java_test(
":testdata",
"//src/test/java/com/google/devtools/build/android/desugar/runtime:throwable_extension_test_utility",
"//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/runtime:throwable_extension",
"//third_party:asm",
"//third_party:guava",
@@ -464,6 +445,7 @@ java_test(
":testdata",
"//src/test/java/com/google/devtools/build/android/desugar/runtime:throwable_extension_test_utility",
"//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/runtime:throwable_extension",
"//third_party:asm",
"//third_party:guava",
@@ -490,6 +472,7 @@ java_test(
":testdata",
"//src/test/java/com/google/devtools/build/android/desugar/runtime:throwable_extension_test_utility",
"//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/runtime:throwable_extension",
"//third_party:asm",
"//third_party:guava",
@@ -1971,6 +1954,7 @@ test_suite(
":windows_tests",
"//src/test/java/com/google/devtools/build/android/desugar/classes_for_testing_type_inference:all_windows_tests",
"//src/test/java/com/google/devtools/build/android/desugar/dependencies:all_windows_tests",
+ "//src/test/java/com/google/devtools/build/android/desugar/io:all_windows_tests",
"//src/test/java/com/google/devtools/build/android/desugar/runtime:all_windows_tests",
],
visibility = ["//src/test/java/com/google/devtools/build/android:__pkg__"],
diff --git a/src/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java b/src/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java
index ec4e16d8dd..42f1f78c97 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.android.desugar;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/CorePackageRenamerTest.java b/src/test/java/com/google/devtools/build/android/desugar/CorePackageRenamerTest.java
index 2bdd58bd8d..5220ed6f18 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/CorePackageRenamerTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/CorePackageRenamerTest.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.android.desugar;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixerTest.java b/src/test/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixerTest.java
index faa6dda932..406a36f481 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixerTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixerTest.java
@@ -19,7 +19,10 @@ import static com.google.devtools.build.android.desugar.DefaultMethodClassFixer.
import com.google.common.collect.ImmutableList;
import com.google.common.io.Closer;
-import com.google.devtools.build.android.desugar.Desugar.ThrowingClassLoader;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
+import com.google.devtools.build.android.desugar.io.HeaderClassLoader;
+import com.google.devtools.build.android.desugar.io.IndexedInputs;
+import com.google.devtools.build.android.desugar.io.ThrowingClassLoader;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/Java7CompatibilityTest.java b/src/test/java/com/google/devtools/build/android/desugar/Java7CompatibilityTest.java
index 2eab943aba..99e51c1551 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/Java7CompatibilityTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/Java7CompatibilityTest.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.android.desugar;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java b/src/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
index 37afae7236..dc0da22d47 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
@@ -25,6 +25,7 @@ import static org.objectweb.asm.Opcodes.ASM5;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import com.google.devtools.build.android.desugar.runtime.ThrowableExtension;
import com.google.devtools.build.android.desugar.testdata.ClassUsingTryWithResources;
import java.io.IOException;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/io/BUILD b/src/test/java/com/google/devtools/build/android/desugar/io/BUILD
new file mode 100644
index 0000000000..d968a7b9b9
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/desugar/io/BUILD
@@ -0,0 +1,53 @@
+# Description:
+# Tests for the Java 8 desugaring tool for Android.
+package(
+ default_testonly = 1,
+)
+
+licenses(["notice"]) # Apache 2.0
+
+filegroup(
+ name = "srcs",
+ testonly = 0,
+ srcs = glob(["**"]),
+ visibility = ["//src/test/java/com/google/devtools/build/android/desugar:__pkg__"],
+)
+
+java_test(
+ name = "FieldInfoTest",
+ size = "small",
+ srcs = ["FieldInfoTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android/desugar/io",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
+ name = "IndexedInputsTest",
+ size = "small",
+ srcs = ["IndexedInputsTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android/desugar/io",
+ "//third_party:guava",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+test_suite(
+ name = "windows_tests",
+ tags = [
+ "-no_windows",
+ "-slow",
+ ],
+)
+
+test_suite(
+ name = "all_windows_tests",
+ tests = [
+ ":windows_tests",
+ ],
+ visibility = ["//src/test/java/com/google/devtools/build/android/desugar:__pkg__"],
+)
diff --git a/src/test/java/com/google/devtools/build/android/desugar/FieldInfoTest.java b/src/test/java/com/google/devtools/build/android/desugar/io/FieldInfoTest.java
index afb2beacbd..0579822328 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/FieldInfoTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/io/FieldInfoTest.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import static com.google.common.truth.Truth.assertThat;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/IndexedInputsTest.java b/src/test/java/com/google/devtools/build/android/desugar/io/IndexedInputsTest.java
index bac3fc92cd..81a4b31c3c 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/IndexedInputsTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/io/IndexedInputsTest.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import static com.google.common.truth.Truth.assertThat;
diff --git a/src/test/java/com/google/devtools/build/android/desugar/scan/testdata/CollectionReferences.java b/src/test/java/com/google/devtools/build/android/desugar/scan/testdata/CollectionReferences.java
index 482c32a9ba..830364c06c 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/scan/testdata/CollectionReferences.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/scan/testdata/CollectionReferences.java
@@ -54,6 +54,10 @@ public class CollectionReferences {
return result;
}
+ public void expire(long before) {
+ dates.removeIf(d -> d.getTime() < before);
+ }
+
static {
System.out.println("Hello!");
}
diff --git a/src/test/java/com/google/devtools/build/android/desugar/scan/testdata_golden.txt b/src/test/java/com/google/devtools/build/android/desugar/scan/testdata_golden.txt
index 35744cefd9..60825763f5 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/scan/testdata_golden.txt
+++ b/src/test/java/com/google/devtools/build/android/desugar/scan/testdata_golden.txt
@@ -18,6 +18,19 @@
-keep class java.lang.System {
*** out;
}
+-keep class java.lang.invoke.CallSite {
+}
+-keep class java.lang.invoke.LambdaMetafactory {
+ *** metafactory(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, java.lang.invoke.MethodType);
+}
+-keep class java.lang.invoke.MethodHandle {
+}
+-keep class java.lang.invoke.MethodHandles {
+}
+-keep class java.lang.invoke.MethodHandles$Lookup {
+}
+-keep class java.lang.invoke.MethodType {
+}
-keep class java.util.AbstractList {
}
-keep class java.util.ArrayList {
@@ -28,6 +41,7 @@
*** iterator();
}
-keep class java.util.Collection {
+ *** removeIf(java.util.function.Predicate);
}
-keep class java.util.Date {
<init>(long);
@@ -44,3 +58,5 @@
*** get(int);
*** iterator();
}
+-keep class java.util.function.Predicate {
+}
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 a75afb2f04..55e3f8bd55 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
@@ -36,6 +36,7 @@ java_library(
":deps_collector_api",
"//src/main/java/com/google/devtools/common/options",
"//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//src/tools/android/java/com/google/devtools/build/android/desugar/io",
"//third_party:asm",
"//third_party:asm-commons",
"//third_party:asm-tree",
@@ -58,6 +59,7 @@ filegroup(
name = "srcs",
srcs = glob(["**"]) + [
"//src/tools/android/java/com/google/devtools/build/android/desugar/dependencies:srcs",
+ "//src/tools/android/java/com/google/devtools/build/android/desugar/io:srcs",
"//src/tools/android/java/com/google/devtools/build/android/desugar/runtime: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/BytecodeTypeInference.java b/src/tools/android/java/com/google/devtools/build/android/desugar/BytecodeTypeInference.java
index 783069fee4..ce36071be4 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/BytecodeTypeInference.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/BytecodeTypeInference.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.ArrayList;
import java.util.Optional;
import javax.annotation.Nullable;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java b/src/tools/android/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java
index bae5251d0b..aff9bab05d 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java
@@ -13,6 +13,9 @@
// limitations under the License.
package com.google.devtools.build.android.desugar;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
+import com.google.devtools.build.android.desugar.io.IndexedInputs;
+import com.google.devtools.build.android.desugar.io.InputFileProvider;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/ClassVsInterface.java b/src/tools/android/java/com/google/devtools/build/android/desugar/ClassVsInterface.java
index cb62deb4b0..272445451b 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/ClassVsInterface.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/ClassVsInterface.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.android.desugar;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.HashMap;
import javax.annotation.Nullable;
import org.objectweb.asm.ClassReader;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibrarySupport.java b/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibrarySupport.java
index da23c1268a..fd10e5e9f1 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibrarySupport.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibrarySupport.java
@@ -25,6 +25,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
+import com.google.devtools.build.android.desugar.io.BitFlags;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
import com.google.errorprone.annotations.Immutable;
import java.lang.reflect.Method;
import java.util.Collection;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java b/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
index 853ed092ad..960cfeb106 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
index 506a380c12..c176f9cfc2 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -27,14 +27,19 @@ import com.google.common.io.ByteStreams;
import com.google.common.io.Closer;
import com.google.devtools.build.android.Converters.ExistingPathConverter;
import com.google.devtools.build.android.Converters.PathConverter;
-import com.google.devtools.build.android.desugar.CoreLibraryRewriter.UnprefixingClassWriter;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter.UnprefixingClassWriter;
+import com.google.devtools.build.android.desugar.io.HeaderClassLoader;
+import com.google.devtools.build.android.desugar.io.IndexedInputs;
+import com.google.devtools.build.android.desugar.io.InputFileProvider;
+import com.google.devtools.build.android.desugar.io.OutputFileProvider;
+import com.google.devtools.build.android.desugar.io.ThrowingClassLoader;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor;
-import com.google.errorprone.annotations.MustBeClosed;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
@@ -386,8 +391,8 @@ class Desugar {
Files.isDirectory(inputPath) || !Files.isDirectory(outputPath),
"Input jar file requires an output jar file");
- try (OutputFileProvider outputFileProvider = toOutputFileProvider(outputPath);
- InputFileProvider inputFiles = toInputFileProvider(inputPath)) {
+ try (OutputFileProvider outputFileProvider = OutputFileProvider.create(outputPath);
+ InputFileProvider inputFiles = InputFileProvider.open(inputPath)) {
DependencyCollector depsCollector = createDepsCollector();
IndexedInputs indexedInputFiles = new IndexedInputs(ImmutableList.of(inputFiles));
// Prepend classpath with input file itself so LambdaDesugaring can load classes with
@@ -942,19 +947,6 @@ class Desugar {
return ioPairListbuilder.build();
}
- @VisibleForTesting
- static class ThrowingClassLoader extends ClassLoader {
- @Override
- protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
- if (name.startsWith("java.")) {
- // Use system class loader for java. classes, since ClassLoader.defineClass gets
- // grumpy when those don't come from the standard place.
- return super.loadClass(name, resolve);
- }
- throw new ClassNotFoundException();
- }
- }
-
private static void deleteTreeOnExit(final Path directory) {
Thread shutdownHook =
new Thread() {
@@ -993,26 +985,6 @@ class Desugar {
}
}
- /** Transform a Path to an {@link OutputFileProvider} */
- @MustBeClosed
- private static OutputFileProvider toOutputFileProvider(Path path) throws IOException {
- if (Files.isDirectory(path)) {
- return new DirectoryOutputFileProvider(path);
- } else {
- return new ZipOutputFileProvider(path);
- }
- }
-
- /** Transform a Path to an InputFileProvider that needs to be closed by the caller. */
- @MustBeClosed
- private static InputFileProvider toInputFileProvider(Path path) throws IOException {
- if (Files.isDirectory(path)) {
- return new DirectoryInputFileProvider(path);
- } else {
- return new ZipInputFileProvider(path);
- }
- }
-
/**
* Transform a list of Path to a list of InputFileProvider and register them with the given
* closer.
@@ -1023,7 +995,7 @@ class Desugar {
Closer closer, List<Path> paths) throws IOException {
ImmutableList.Builder<InputFileProvider> builder = new ImmutableList.Builder<>();
for (Path path : paths) {
- builder.add(closer.register(toInputFileProvider(path)));
+ builder.add(closer.register(InputFileProvider.open(path)));
}
return builder.build();
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/EmulatedInterfaceRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/EmulatedInterfaceRewriter.java
index f066f2a74c..355dd9713c 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/EmulatedInterfaceRewriter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/EmulatedInterfaceRewriter.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.android.desugar;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.Collections;
import java.util.LinkedHashSet;
import org.objectweb.asm.ClassVisitor;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java b/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
index 0a10df1f43..e9e3199428 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
@@ -17,6 +17,8 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import com.google.devtools.build.android.desugar.io.BitFlags;
+import com.google.devtools.build.android.desugar.io.FieldInfo;
import java.lang.reflect.Method;
import javax.annotation.Nullable;
import org.objectweb.asm.AnnotationVisitor;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/Java7Compatibility.java b/src/tools/android/java/com/google/devtools/build/android/desugar/Java7Compatibility.java
index 37a45dd3c0..2090d5ccc2 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/Java7Compatibility.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/Java7Compatibility.java
@@ -17,6 +17,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import javax.annotation.Nullable;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassFixer.java b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassFixer.java
index fb05bcbf91..6b0a9214ee 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassFixer.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassFixer.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.HashSet;
import java.util.LinkedHashSet;
import org.objectweb.asm.AnnotationVisitor;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaDesugaring.java b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaDesugaring.java
index 5f41347be5..f9b531698d 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaDesugaring.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaDesugaring.java
@@ -21,6 +21,7 @@ import static org.objectweb.asm.Opcodes.ASM6;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java
index 6ac415df5b..7f2f35525f 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java
@@ -17,6 +17,7 @@ import static org.objectweb.asm.Opcodes.ASM6;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.LCMP;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java
index 5e0a3441a7..931459ae0e 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java
@@ -19,6 +19,7 @@ import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.POP;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
index e8509e71d1..818585f20f 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
@@ -29,6 +29,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.android.desugar.BytecodeTypeInference.InferredType;
+import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Optional;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/io/BUILD b/src/tools/android/java/com/google/devtools/build/android/desugar/io/BUILD
new file mode 100644
index 0000000000..7b84a94c0d
--- /dev/null
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/BUILD
@@ -0,0 +1,25 @@
+# Description:
+# Tool for desugaring Java constructs not supported by Android tools or devices.
+
+java_library(
+ name = "io",
+ srcs = glob(["*.java"]),
+ visibility = [
+ "//src/test/java/com/google/devtools/build/android/desugar:__subpackages__",
+ "//src/tools/android/java/com/google/devtools/build/android/desugar:__pkg__",
+ ],
+ deps = [
+ "//third_party:asm",
+ "//third_party:asm-commons",
+ "//third_party:asm-tree",
+ "//third_party:auto_value",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ ],
+)
+
+filegroup(
+ name = "srcs",
+ srcs = glob(["**"]),
+ visibility = ["//src/tools/android/java/com/google/devtools/build/android/desugar:__pkg__"],
+)
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/BitFlags.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/BitFlags.java
index 8be228801d..af6f48130e 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/BitFlags.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/BitFlags.java
@@ -11,12 +11,12 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import org.objectweb.asm.Opcodes;
/** Convenience method for working with {@code int} bitwise flags. */
-class BitFlags {
+public class BitFlags {
/**
* Returns {@code true} iff <b>all</b> bits in {@code bitmask} are set in {@code flags}. Trivially
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/CoreLibraryRewriter.java
index 698fc53a39..f3c546c1c3 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/CoreLibraryRewriter.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import java.io.IOException;
import java.io.InputStream;
@@ -25,7 +25,7 @@ import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
/** Utility class to prefix or unprefix class names of core library classes */
-class CoreLibraryRewriter {
+public class CoreLibraryRewriter {
private final String prefix;
public CoreLibraryRewriter(String prefix) {
@@ -178,11 +178,11 @@ class CoreLibraryRewriter {
/** Returns the (unprefixed) name of the class once written. */
@Nullable
- String getClassName() {
+ public String getClassName() {
return finalClassName;
}
- byte[] toByteArray() {
+ public byte[] toByteArray() {
return writer.toByteArray();
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/DirectoryInputFileProvider.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/DirectoryInputFileProvider.java
index 1c5abc9dca..c607b4233b 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/DirectoryInputFileProvider.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/DirectoryInputFileProvider.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import java.io.File;
import java.io.FileInputStream;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/DirectoryOutputFileProvider.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/DirectoryOutputFileProvider.java
index 782a81ea2b..f8e87cbb33 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/DirectoryOutputFileProvider.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/DirectoryOutputFileProvider.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import com.google.common.io.ByteStreams;
import java.io.IOException;
@@ -21,7 +21,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
/** Output provider is a directory. */
-public class DirectoryOutputFileProvider implements OutputFileProvider {
+class DirectoryOutputFileProvider implements OutputFileProvider {
private final Path root;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/FieldInfo.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/FieldInfo.java
index c281039f61..0b4f63418b 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/FieldInfo.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/FieldInfo.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import com.google.auto.value.AutoValue;
@@ -19,7 +19,7 @@ import com.google.auto.value.AutoValue;
@AutoValue
public abstract class FieldInfo {
- static FieldInfo create(String owner, String name, String desc) {
+ public static FieldInfo create(String owner, String name, String desc) {
return new AutoValue_FieldInfo(owner, name, desc);
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/HeaderClassLoader.java
index 77d99bb01c..f70dc0e3e2 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/HeaderClassLoader.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import com.google.common.collect.ImmutableList;
import java.io.IOError;
@@ -33,7 +33,7 @@ import org.objectweb.asm.Opcodes;
*
* @see java.net.URLClassLoader
*/
-class HeaderClassLoader extends ClassLoader {
+public class HeaderClassLoader extends ClassLoader {
private final IndexedInputs indexedInputs;
private final CoreLibraryRewriter rewriter;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/IndexedInputs.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/IndexedInputs.java
index 33c6132020..8ce4b62302 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/IndexedInputs.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/IndexedInputs.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
@@ -28,7 +28,7 @@ import javax.annotation.Nullable;
* scanning all inputs over and over for each class to load. An indexed inputs can have a parent
* that is firstly used when a file name is searched.
*/
-class IndexedInputs {
+public class IndexedInputs {
private final ImmutableMap<String, InputFileProvider> inputFiles;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/InputFileProvider.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/InputFileProvider.java
index c2b63532da..c41d018df8 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/InputFileProvider.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/InputFileProvider.java
@@ -11,15 +11,18 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
+import com.google.errorprone.annotations.MustBeClosed;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.zip.ZipEntry;
/** Input file provider allows to iterate on relative path filename of a directory or a jar file. */
-interface InputFileProvider extends Closeable, Iterable<String> {
+public interface InputFileProvider extends Closeable, Iterable<String> {
/**
* Return a ZipEntry for {@code filename}. If the provider is a {@link ZipInputFileProvider}, the
@@ -33,4 +36,14 @@ interface InputFileProvider extends Closeable, Iterable<String> {
* responsibility of the caller to close this stream.
*/
InputStream getInputStream(String filename) throws IOException;
+
+ /** Transform a Path to an InputFileProvider that needs to be closed by the caller. */
+ @MustBeClosed
+ public static InputFileProvider open(Path path) throws IOException {
+ if (Files.isDirectory(path)) {
+ return new DirectoryInputFileProvider(path);
+ } else {
+ return new ZipInputFileProvider(path);
+ }
+ }
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/OutputFileProvider.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/OutputFileProvider.java
index 7a590ef2ba..e693786082 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/OutputFileProvider.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/OutputFileProvider.java
@@ -11,12 +11,15 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
+import com.google.errorprone.annotations.MustBeClosed;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
/** Output file provider allows to write files in directory or jar files. */
-interface OutputFileProvider extends AutoCloseable {
+public interface OutputFileProvider extends AutoCloseable {
/** Filename to use to write out dependency metadata for later consistency checking. */
public static final String DESUGAR_DEPS_FILENAME = "META-INF/desugar_deps";
@@ -29,4 +32,14 @@ interface OutputFileProvider extends AutoCloseable {
/** Write {@code content} in {@code filename} to this output */
void write(String filename, byte[] content) throws IOException;
+
+ /** Transform a Path to an {@link OutputFileProvider} */
+ @MustBeClosed
+ public static OutputFileProvider create(Path path) throws IOException {
+ if (Files.isDirectory(path)) {
+ return new DirectoryOutputFileProvider(path);
+ } else {
+ return new ZipOutputFileProvider(path);
+ }
+ }
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/io/ThrowingClassLoader.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/ThrowingClassLoader.java
new file mode 100644
index 0000000000..16f83f22e4
--- /dev/null
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/ThrowingClassLoader.java
@@ -0,0 +1,27 @@
+// Copyright 2016 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.io;
+
+/** Class loader that throws whenever it can, for use the parent of a class loader hierarchy. */
+public class ThrowingClassLoader extends ClassLoader {
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (name.startsWith("java.")) {
+ // Use system class loader for java. classes, since ClassLoader.defineClass gets
+ // grumpy when those don't come from the standard place.
+ return super.loadClass(name, resolve);
+ }
+ throw new ClassNotFoundException();
+ }
+} \ No newline at end of file
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/ZipInputFileProvider.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/ZipInputFileProvider.java
index 307c8b83e6..9bd7758952 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/ZipInputFileProvider.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/ZipInputFileProvider.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import com.google.common.base.Functions;
import com.google.common.collect.Iterators;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/ZipOutputFileProvider.java b/src/tools/android/java/com/google/devtools/build/android/desugar/io/ZipOutputFileProvider.java
index 8d6501d198..36cb26d157 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/ZipOutputFileProvider.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/io/ZipOutputFileProvider.java
@@ -11,7 +11,7 @@
// 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;
+package com.google.devtools.build.android.desugar.io;
import static com.google.common.base.Preconditions.checkArgument;
@@ -26,7 +26,7 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** Output provider is a zip file. */
-public class ZipOutputFileProvider implements OutputFileProvider {
+class ZipOutputFileProvider implements OutputFileProvider {
private final ZipOutputStream out;
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/scan/KeepScanner.java b/src/tools/android/java/com/google/devtools/build/android/desugar/scan/KeepScanner.java
index b347c7a659..4924f7c002 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/scan/KeepScanner.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/scan/KeepScanner.java
@@ -15,13 +15,21 @@ package com.google.devtools.build.android.desugar.scan;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.util.Comparator.comparing;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
+import com.google.common.io.Closer;
import com.google.devtools.build.android.Converters.ExistingPathConverter;
import com.google.devtools.build.android.Converters.PathConverter;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
+import com.google.devtools.build.android.desugar.io.HeaderClassLoader;
+import com.google.devtools.build.android.desugar.io.IndexedInputs;
+import com.google.devtools.build.android.desugar.io.InputFileProvider;
+import com.google.devtools.build.android.desugar.io.ThrowingClassLoader;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
@@ -32,9 +40,11 @@ import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
+import java.lang.reflect.Method;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
@@ -57,6 +67,32 @@ class KeepScanner {
public Path inputJars;
@Option(
+ name = "classpath_entry",
+ allowMultiple = true,
+ defaultValue = "",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ converter = ExistingPathConverter.class,
+ help =
+ "Ordered classpath (Jar or directory) to resolve symbols in the --input Jar, like "
+ + "javac's -cp flag."
+ )
+ public List<Path> classpath;
+
+ @Option(
+ name = "bootclasspath_entry",
+ allowMultiple = true,
+ defaultValue = "",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ converter = ExistingPathConverter.class,
+ help =
+ "Bootclasspath that was used to compile the --input Jar with, like javac's "
+ + "-bootclasspath flag (required)."
+ )
+ public List<Path> bootclasspath;
+
+ @Option(
name = "keep_file",
defaultValue = "null",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
@@ -81,10 +117,25 @@ class KeepScanner {
parser.setAllowResidue(false);
parser.enableParamsFileSupport(new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()));
parser.parseAndExitUponError(args);
-
KeepScannerOptions options = parser.getOptions(KeepScannerOptions.class);
- Map<String, ImmutableSet<KeepReference>> seeds =
- scan(checkNotNull(options.inputJars), options.prefix);
+
+ Map<String, ImmutableSet<KeepReference>> seeds;
+ try (Closer closer = Closer.create()) {
+ // TODO(kmb): Try to share more of this code with Desugar binary
+ IndexedInputs classpath =
+ new IndexedInputs(toRegisteredInputFileProvider(closer, options.classpath));
+ IndexedInputs bootclasspath =
+ new IndexedInputs(toRegisteredInputFileProvider(closer, options.bootclasspath));
+
+ // Construct classloader from classpath. Since we're assuming the prefix we're looking for
+ // isn't part of the input itself we shouldn't need to include the input in the classloader.
+ CoreLibraryRewriter noopRewriter = new CoreLibraryRewriter("");
+ ClassLoader classloader =
+ new HeaderClassLoader(classpath, noopRewriter,
+ new HeaderClassLoader(bootclasspath, noopRewriter,
+ new ThrowingClassLoader()));
+ seeds = scan(checkNotNull(options.inputJars), options.prefix, classloader);
+ }
try (PrintStream out =
new PrintStream(
@@ -117,11 +168,9 @@ class KeepScanner {
});
}
- /**
- * Scans for and returns references with owners matching the given prefix grouped by owner.
- */
- private static Map<String, ImmutableSet<KeepReference>> scan(Path jarFile, String prefix)
- throws IOException {
+ /** Scans for and returns references with owners matching the given prefix grouped by owner. */
+ private static Map<String, ImmutableSet<KeepReference>> scan(
+ Path jarFile, String prefix, ClassLoader classpath) throws IOException {
// We read the Jar sequentially since ZipFile uses locks anyway but then allow scanning each
// class in parallel.
try (ZipFile zip = new ZipFile(jarFile.toFile())) {
@@ -131,6 +180,8 @@ class KeepScanner {
.parallel()
.flatMap(
content -> PrefixReferenceScanner.scan(new ClassReader(content), prefix).stream())
+ .distinct() // so we don't process the same reference multiple times next
+ .map(ref -> nearestDeclaration(ref, classpath))
.collect(
Collectors.groupingByConcurrent(
KeepReference::internalName, ImmutableSet.toImmutableSet()));
@@ -147,6 +198,68 @@ class KeepScanner {
}
}
+ /**
+ * Find the nearest definition of the given reference in the class hierarchy and return the
+ * modified reference. This is needed b/c bytecode sometimes refers to a method or field using
+ * an owner type that inherits the method or field instead of defining the member itself.
+ * In that case we need to find and keep the inherited definition.
+ */
+ private static KeepReference nearestDeclaration(KeepReference ref, ClassLoader classpath) {
+ if (!ref.isMemberReference() || "<init>".equals(ref.name())) {
+ return ref; // class and constructor references don't need any further work
+ }
+
+ Class<?> clazz;
+ try {
+ clazz = classpath.loadClass(ref.internalName().replace('/', '.'));
+ } catch (ClassNotFoundException e) {
+ throw (NoClassDefFoundError) new NoClassDefFoundError("Couldn't load " + ref).initCause(e);
+ }
+
+ Class<?> owner = findDeclaringClass(clazz, ref);
+ if (owner == clazz) {
+ return ref;
+ }
+ String parent = checkNotNull(owner, "Can't resolve: %s", ref).getName().replace('.', '/');
+ return KeepReference.memberReference(parent, ref.name(), ref.desc());
+ }
+
+ private static Class<?> findDeclaringClass(Class<?> clazz, KeepReference ref) {
+ if (ref.isFieldReference()) {
+ try {
+ return clazz.getField(ref.name()).getDeclaringClass();
+ } catch (NoSuchFieldException e) {
+ // field must be non-public, so search class hierarchy
+ do {
+ try {
+ return clazz.getDeclaredField(ref.name()).getDeclaringClass();
+ } catch (NoSuchFieldException ignored) {
+ // fall through for clarity
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz != null);
+ }
+ } else {
+ checkState(ref.isMethodReference());
+ Type descriptor = Type.getMethodType(ref.desc());
+ for (Method m : clazz.getMethods()) {
+ if (m.getName().equals(ref.name()) && Type.getType(m).equals(descriptor)) {
+ return m.getDeclaringClass();
+ }
+ }
+ do {
+ // Method must be non-public, so search class hierarchy
+ for (Method m : clazz.getDeclaredMethods()) {
+ if (m.getName().equals(ref.name()) && Type.getType(m).equals(descriptor)) {
+ return m.getDeclaringClass();
+ }
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz != null);
+ }
+ return null;
+ }
+
private static CharSequence toKeepDescriptor(KeepReference member) {
StringBuilder result = new StringBuilder();
if (member.isMethodReference()) {
@@ -172,5 +285,19 @@ class KeepScanner {
return result;
}
+ /**
+ * Transform a list of Path to a list of InputFileProvider and register them with the given
+ * closer.
+ */
+ @SuppressWarnings("MustBeClosedChecker")
+ private static ImmutableList<InputFileProvider> toRegisteredInputFileProvider(
+ Closer closer, List<Path> paths) throws IOException {
+ ImmutableList.Builder<InputFileProvider> builder = new ImmutableList.Builder<>();
+ for (Path path : paths) {
+ builder.add(closer.register(InputFileProvider.open(path)));
+ }
+ return builder.build();
+ }
+
private KeepScanner() {}
}