summaryrefslogtreecommitdiff
path: root/java/com/google/devtools/build/android/desugar/Desugar.java
diff options
context:
space:
mode:
authorcnsun <cnsun@google.com>2017-06-28 18:05:48 +0200
committerColin Cross <ccross@android.com>2017-06-30 18:41:09 -0700
commitc250c8b7473328ac228493c305f632191ac5c8ad (patch)
treec256bbcb844004c9b4a2fd373192bdf699f4bdc8 /java/com/google/devtools/build/android/desugar/Desugar.java
parent3d23220776fbf3dcd4fb1aa7e2cc0c208bb4e7db (diff)
downloaddesugar-c250c8b7473328ac228493c305f632191ac5c8ad.tar.gz
Access interface constants to explicitly trigger the execution of interface
initializers. The problem is that when we desugar default methods, the static intializer of interface will not be executed. The JVM spec says that if an interface has default methods, then when it is loaded, it will also be initialized. After we desugar such an interface, its default methods are removed, and when we load the interface, the <clinit> will not be executed. This CL checks whether an interface has default methods and fields. If yes (needs to be initialized when the interface is loaded), it injects field access code to access the interface fields in the <clinit> of the companion class. We also create a constant $$CONSTANT$$ in the companion class. Then for all the classes that implement the interface, we inject GETSTATIC in the class <clinit> to the $$CONSTANT$$ of the companion class of the interface. This indirection is to avoid the IllegalAccessError when the interface is package private. Note that accessing an arbitrary interface field does not guarantee the interface will be initialized. We need to access the field that is initialized in the interface static initializer. RELNOTES: None PiperOrigin-RevId: 160414671 GitOrigin-RevId: 8740ca6bd0f4156aaf663c482bc3e9c7ebb2c556 Change-Id: I221d094c82d5bffa9b0a1f2082192b3211e70ea9
Diffstat (limited to 'java/com/google/devtools/build/android/desugar/Desugar.java')
-rw-r--r--java/com/google/devtools/build/android/desugar/Desugar.java7
1 files changed, 5 insertions, 2 deletions
diff --git a/java/com/google/devtools/build/android/desugar/Desugar.java b/java/com/google/devtools/build/android/desugar/Desugar.java
index bbba22e..74dfa17 100644
--- a/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -20,6 +20,7 @@ import static com.google.devtools.build.android.desugar.LambdaClassMaker.LAMBDA_
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import com.google.auto.value.AutoValue;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -625,7 +626,8 @@ class Desugar {
return ioPairListbuilder.build();
}
- private static class ThrowingClassLoader extends ClassLoader {
+ @VisibleForTesting
+ static class ThrowingClassLoader extends ClassLoader {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("java.")) {
@@ -700,7 +702,8 @@ class Desugar {
* closer.
*/
@SuppressWarnings("MustBeClosedChecker")
- private static ImmutableList<InputFileProvider> toRegisteredInputFileProvider(
+ @VisibleForTesting
+ static ImmutableList<InputFileProvider> toRegisteredInputFileProvider(
Closer closer, List<Path> paths) throws IOException {
ImmutableList.Builder<InputFileProvider> builder = new ImmutableList.Builder<>();
for (Path path : paths) {