summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2017-05-02 17:13:34 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-05-02 17:13:34 +0000
commit17df38ab042e1294f828333b0cd7f06a0858ac42 (patch)
tree6c0ec8bf5208bfe19fc41292a29cd914f350ba25
parentce7ccb0464c16d761f6e395bef9d35e9f78edec6 (diff)
parentdeaba3bcbb075ef523ec09592af745a2be944290 (diff)
downloaddesugar-17df38ab042e1294f828333b0cd7f06a0858ac42.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' into desugar am: e3fedeb000 am: 36c2d50414
am: deaba3bcbb Change-Id: I6b6426a8d3dfa528cb4545a712c420de53edb8bc
-rw-r--r--java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java22
-rw-r--r--java/com/google/devtools/build/android/desugar/Desugar.java12
-rw-r--r--java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java20
3 files changed, 43 insertions, 11 deletions
diff --git a/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java b/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
index 8ad5dc2..732f064 100644
--- a/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
+++ b/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
@@ -132,6 +132,19 @@ public class DefaultMethodClassFixer extends ClassVisitor {
return false;
}
+ /**
+ * Returns {@code true} for non-bridge default methods not in {@link #instanceMethods}.
+ */
+ private boolean shouldStub(int access, String name, String desc) {
+ // Ignore private methods, which technically aren't default methods and can only be called from
+ // other methods defined in the interface. This also ignores lambda body methods, which is fine
+ // as we don't want or need to stub those. Also ignore bridge methods as javac adds them to
+ // concrete classes as needed anyway and we handle them separately for generated lambda classes.
+ return BitFlags.noneSet(access,
+ Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_PRIVATE)
+ && !instanceMethods.contains(name + ":" + desc);
+ }
+
private void stubMissingDefaultMethods(ImmutableList<String> interfaces) {
for (String implemented : interfaces) {
if (!seenInterfaces.add(implemented)) {
@@ -183,12 +196,10 @@ public class DefaultMethodClassFixer extends ClassVisitor {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
- if (BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE)
- && !instanceMethods.contains(name + ":" + desc)) {
+ if (shouldStub(access, name, desc)) {
// Add this method to the class we're desugaring and stub in a body to call the default
// implementation in the interface's companion class. ijar omits these methods when setting
- // ACC_SYNTHETIC modifier, so don't. Don't do this for bridge methods, which we handle
- // separately.
+ // ACC_SYNTHETIC modifier, so don't.
// Signatures can be wrong, e.g., when type variables are introduced, instantiated, or
// refined in the class we're processing, so drop them.
MethodVisitor stubMethod =
@@ -255,8 +266,7 @@ public class DefaultMethodClassFixer extends ClassVisitor {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
- if (BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE)
- && !instanceMethods.contains(name + ":" + desc)) {
+ if (!found && shouldStub(access, name, desc)) {
// Found a default method we're not ignoring (instanceMethods at this point contains methods
// the top-level visited class implements itself).
found = true;
diff --git a/java/com/google/devtools/build/android/desugar/Desugar.java b/java/com/google/devtools/build/android/desugar/Desugar.java
index c4528ae..ca7032e 100644
--- a/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -522,15 +522,19 @@ class Desugar {
* LambdaClassMaker generates lambda classes for us, but it does so by essentially simulating the
* call to LambdaMetafactory that the JVM would make when encountering an invokedynamic.
* LambdaMetafactory is in the JDK and its implementation has a property to write out ("dump")
- * generated classes, which we take advantage of here. Set property before doing anything else
- * since the property is read in the static initializer; if this breaks we can investigate setting
- * the property when calling the tool.
+ * generated classes, which we take advantage of here. This property can be set externally, and in
+ * that case the specified directory is used as a temporary dir. Otherwise, it will be set here,
+ * before doing anything else since the property is read in the static initializer.
*/
private static Path createAndRegisterLambdaDumpDirectory() throws IOException {
+ String propertyValue = System.getProperty(LambdaClassMaker.LAMBDA_METAFACTORY_DUMPER_PROPERTY);
+ if (propertyValue != null) {
+ return Paths.get(propertyValue);
+ }
+
Path dumpDirectory = Files.createTempDirectory("lambdas");
System.setProperty(
LambdaClassMaker.LAMBDA_METAFACTORY_DUMPER_PROPERTY, dumpDirectory.toString());
-
deleteTreeOnExit(dumpDirectory);
return dumpDirectory;
}
diff --git a/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java b/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
index 2429d2f..cde223e 100644
--- a/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
+++ b/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
@@ -85,6 +85,11 @@ public class TryWithResourcesRewriter extends ClassVisitor {
private final ClassLoader classLoader;
private final AtomicInteger numOfTryWithResourcesInvoked;
+ /**
+ * Indicate whether the current class being desugared should be ignored. If the current class is
+ * one of the runtime extension classes, then it should be ignored.
+ */
+ private boolean shouldCurrentClassBeIgnored;
public TryWithResourcesRewriter(
ClassVisitor classVisitor,
@@ -96,10 +101,23 @@ public class TryWithResourcesRewriter extends ClassVisitor {
}
@Override
+ public void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces) {
+ super.visit(version, access, name, signature, superName, interfaces);
+ shouldCurrentClassBeIgnored = THROWABLE_EXT_CLASS_INTERNAL_NAMES.contains(name);
+ }
+
+
+ @Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor visitor = super.cv.visitMethod(access, name, desc, signature, exceptions);
- return visitor == null || THROWABLE_EXT_CLASS_INTERNAL_NAMES.contains(name)
+ return visitor == null || shouldCurrentClassBeIgnored
? visitor
: new TryWithResourceVisitor(visitor, classLoader);
}