diff options
author | cnsun <cnsun@google.com> | 2017-11-14 14:03:09 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2017-11-29 11:28:27 -0800 |
commit | f0971e886d2142be6219bb4a0ffa03f26b02f110 (patch) | |
tree | 31ba0cfa1fa639cda488ce1c736f15e652b38443 /test/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriterTest.java | |
parent | 8daf1cc87a760edfda738e11be41d61776b4e630 (diff) | |
download | desugar-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.java | 28 |
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) { |