summaryrefslogtreecommitdiff
path: root/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
diff options
context:
space:
mode:
authorcnsun <cnsun@google.com>2017-11-14 14:03:09 -0800
committerColin Cross <ccross@android.com>2017-11-29 11:28:27 -0800
commitf0971e886d2142be6219bb4a0ffa03f26b02f110 (patch)
tree31ba0cfa1fa639cda488ce1c736f15e652b38443 /test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
parent8daf1cc87a760edfda738e11be41d61776b4e630 (diff)
downloaddesugar-f0971e886d2142be6219bb4a0ffa03f26b02f110.tar.gz
Specialize $closeResource(Throwable, AutoCloseable) so that desugared code does not depend on AutoCloseable, as it is not available before API 19.
This CL includes the following: 1. A type inference algorithm based on ASM. It relies on the stack map frames to compute type information at the entry of basic blocks. 2. The type inference is used to infer the types of the resources to be closed. Then for each concrete resource type, we specialize the synthetic $closeResource method to $closeResource(Throwable, <concrete resource type>). RELNOTES: None PiperOrigin-RevId: 175731437 GitOrigin-RevId: e83f3b1fb010298cbe1e16e5f7f2f39bfb045cef Change-Id: I347f8e4058a191621fb21bf2e81d7cf8f39ce6aa
Diffstat (limited to 'test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java')
-rw-r--r--test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java28
1 files changed, 23 insertions, 5 deletions
diff --git a/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java b/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
index 587d4f7..37afae7 100644
--- a/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
+++ b/test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java
@@ -206,16 +206,20 @@ public class TryWithResourcesRewriterTest {
.isEqualTo(orig.countExtPrintStackTracePrintWriter());
assertThat(orig.countThrowableGetSuppressed()).isEqualTo(desugared.countExtGetSuppressed());
- // $closeResource is rewritten to ThrowableExtension.closeResource, so addSuppressed() is called
- // in the runtime library now.
- assertThat(orig.countThrowableAddSuppressed())
- .isAtLeast(desugared.countThrowableAddSuppressed());
+ // $closeResource may be specialized into multiple versions.
+ assertThat(orig.countThrowableAddSuppressed()).isAtMost(desugared.countExtAddSuppressed());
assertThat(orig.countThrowablePrintStackTrace()).isEqualTo(desugared.countExtPrintStackTrace());
assertThat(orig.countThrowablePrintStackTracePrintStream())
.isEqualTo(desugared.countExtPrintStackTracePrintStream());
assertThat(orig.countThrowablePrintStackTracePrintWriter())
.isEqualTo(desugared.countExtPrintStackTracePrintWriter());
+ if (orig.getSyntheticCloseResourceCount() > 0) {
+ // Depending on the specific javac version, $closeResource(Throwable, AutoCloseable) may not
+ // be there.
+ assertThat(orig.getSyntheticCloseResourceCount()).isEqualTo(1);
+ assertThat(desugared.getSyntheticCloseResourceCount()).isAtLeast(1);
+ }
assertThat(desugared.countThrowablePrintStackTracePrintStream()).isEqualTo(0);
assertThat(desugared.countThrowablePrintStackTracePrintStream()).isEqualTo(0);
assertThat(desugared.countThrowablePrintStackTracePrintWriter()).isEqualTo(0);
@@ -270,6 +274,7 @@ public class TryWithResourcesRewriterTest {
private static class DesugaredThrowableMethodCallCounter extends ClassVisitor {
private final ClassLoader classLoader;
private final Map<String, AtomicInteger> counterMap;
+ private int syntheticCloseResourceCount;
public DesugaredThrowableMethodCallCounter(ClassLoader loader) {
super(ASM5);
@@ -291,6 +296,12 @@ public class TryWithResourcesRewriterTest {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
+ if (BitFlags.isSet(access, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC)
+ && name.equals("$closeResource")
+ && Type.getArgumentTypes(desc).length == 2
+ && Type.getArgumentTypes(desc)[0].getDescriptor().equals("Ljava/lang/Throwable;")) {
+ ++syntheticCloseResourceCount;
+ }
return new InvokeCounter();
}
@@ -324,6 +335,10 @@ public class TryWithResourcesRewriterTest {
}
}
+ public int getSyntheticCloseResourceCount() {
+ return syntheticCloseResourceCount;
+ }
+
public int countThrowableAddSuppressed() {
return counterMap.get("addSuppressed(Ljava/lang/Throwable;)V").get();
}
@@ -396,13 +411,16 @@ public class TryWithResourcesRewriterTest {
private byte[] desugarTryWithResources(String className) {
try {
ClassReader reader = new ClassReader(className);
+ CloseResourceMethodScanner scanner = new CloseResourceMethodScanner();
+ reader.accept(scanner, ClassReader.SKIP_DEBUG);
ClassWriter writer = new ClassWriter(reader, COMPUTE_MAXS);
TryWithResourcesRewriter rewriter =
new TryWithResourcesRewriter(
writer,
TryWithResourcesRewriterTest.class.getClassLoader(),
visitedExceptionTypes,
- numOfTryWithResourcesInvoked);
+ numOfTryWithResourcesInvoked,
+ scanner.hasCloseResourceMethod());
reader.accept(rewriter, 0);
return writer.toByteArray();
} catch (IOException e) {