From b104f2eaa4f376eb2c3b94ec16a7ef44c1c286b1 Mon Sep 17 00:00:00 2001 From: kmb Date: Sat, 10 Feb 2018 12:16:21 -0800 Subject: Desugar fixes: - make Objects.requireNonNull and Long.compare rewrites compatible with --core_library - apply those and try-with-resources rewrites to generated companion classes RELNOTES: None. PiperOrigin-RevId: 185262256 GitOrigin-RevId: f13a7ef7c9eb7ce400ffbbaca0bdc7945172a332 Change-Id: I07a3e5877bc7de8cdade93a6748d511a7669cafe --- .../devtools/build/android/desugar/Desugar.java | 35 ++++++++++++++++++---- .../android/desugar/LongCompareMethodRewriter.java | 19 +++++++----- .../ObjectsRequireNonNullMethodRewriter.java | 30 ++++++++++--------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/java/com/google/devtools/build/android/desugar/Desugar.java b/java/com/google/devtools/build/android/desugar/Desugar.java index 109093c..053e55e 100644 --- a/java/com/google/devtools/build/android/desugar/Desugar.java +++ b/java/com/google/devtools/build/android/desugar/Desugar.java @@ -412,7 +412,9 @@ class Desugar { interfaceLambdaMethodCollector.build(), bridgeMethodReader); - desugarAndWriteGeneratedClasses(outputFileProvider, bootclasspathReader, coreLibrarySupport); + desugarAndWriteGeneratedClasses( + outputFileProvider, loader, bootclasspathReader, coreLibrarySupport); + copyThrowableExtensionClass(outputFileProvider); byte[] depsInfo = depsCollector.toByteArray(); @@ -586,6 +588,7 @@ class Desugar { private void desugarAndWriteGeneratedClasses( OutputFileProvider outputFileProvider, + ClassLoader loader, ClassReaderFactory bootclasspathReader, @Nullable CoreLibrarySupport coreLibrarySupport) throws IOException { @@ -605,6 +608,26 @@ class Desugar { visitor = new CoreLibraryInvocationRewriter(visitor, coreLibrarySupport); } + if (!allowTryWithResources) { + CloseResourceMethodScanner closeResourceMethodScanner = new CloseResourceMethodScanner(); + generated.getValue().accept(closeResourceMethodScanner); + visitor = + new TryWithResourcesRewriter( + visitor, + loader, + visitedExceptionTypes, + numOfTryWithResourcesInvoked, + closeResourceMethodScanner.hasCloseResourceMethod()); + } + if (!allowCallsToObjectsNonNull) { + // Not sure whether there will be implicit null check emitted by javac, so we rerun + // the inliner again + visitor = new ObjectsRequireNonNullMethodRewriter(visitor, rewriter); + } + if (!allowCallsToLongCompare) { + visitor = new LongCompareMethodRewriter(visitor, rewriter); + } + visitor = new Java7Compatibility(visitor, (ClassReaderFactory) null, bootclasspathReader); generated.getValue().accept(visitor); checkState( @@ -651,10 +674,10 @@ class Desugar { if (!allowCallsToObjectsNonNull) { // Not sure whether there will be implicit null check emitted by javac, so we rerun // the inliner again - visitor = new ObjectsRequireNonNullMethodRewriter(visitor); + visitor = new ObjectsRequireNonNullMethodRewriter(visitor, rewriter); } if (!allowCallsToLongCompare) { - visitor = new LongCompareMethodRewriter(visitor); + visitor = new LongCompareMethodRewriter(visitor, rewriter); } if (outputJava7) { // null ClassReaderFactory b/c we don't expect to need it for lambda classes @@ -730,10 +753,10 @@ class Desugar { closeResourceMethodScanner.hasCloseResourceMethod()); } if (!allowCallsToObjectsNonNull) { - visitor = new ObjectsRequireNonNullMethodRewriter(visitor); + visitor = new ObjectsRequireNonNullMethodRewriter(visitor, rewriter); } if (!allowCallsToLongCompare) { - visitor = new LongCompareMethodRewriter(visitor); + visitor = new LongCompareMethodRewriter(visitor, rewriter); } if (!options.onlyDesugarJavac9ForLint) { if (outputJava7) { @@ -840,7 +863,7 @@ class Desugar { return dumpDirectory; } - private static DesugarOptions parseCommandLineOptions(String[] args) throws IOException { + private static DesugarOptions parseCommandLineOptions(String[] args) { OptionsParser parser = OptionsParser.newOptionsParser(DesugarOptions.class); parser.setAllowResidue(false); parser.enableParamsFileSupport(new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault())); diff --git a/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java b/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java index f66d862..6ac415d 100644 --- a/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java +++ b/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java @@ -26,8 +26,11 @@ import org.objectweb.asm.MethodVisitor; */ public class LongCompareMethodRewriter extends ClassVisitor { - public LongCompareMethodRewriter(ClassVisitor cv) { + private final CoreLibraryRewriter rewriter; + + public LongCompareMethodRewriter(ClassVisitor cv, CoreLibraryRewriter rewriter) { super(ASM6, cv); + this.rewriter = rewriter; } @Override @@ -37,7 +40,7 @@ public class LongCompareMethodRewriter extends ClassVisitor { return visitor == null ? visitor : new LongCompareMethodVisitor(visitor); } - private static class LongCompareMethodVisitor extends MethodVisitor { + private class LongCompareMethodVisitor extends MethodVisitor { public LongCompareMethodVisitor(MethodVisitor visitor) { super(ASM6, visitor); @@ -45,14 +48,14 @@ public class LongCompareMethodRewriter extends ClassVisitor { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - if (opcode != INVOKESTATIC - || !owner.equals("java/lang/Long") - || !name.equals("compare") - || !desc.equals("(JJ)I")) { + if (opcode == INVOKESTATIC + && rewriter.unprefix(owner).equals("java/lang/Long") + && name.equals("compare") + && desc.equals("(JJ)I")) { + super.visitInsn(LCMP); + } else { super.visitMethodInsn(opcode, owner, name, desc, itf); - return; } - super.visitInsn(LCMP); } } } diff --git a/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java b/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java index 86465d6..5e0a344 100644 --- a/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java +++ b/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java @@ -29,8 +29,11 @@ import org.objectweb.asm.MethodVisitor; */ public class ObjectsRequireNonNullMethodRewriter extends ClassVisitor { - public ObjectsRequireNonNullMethodRewriter(ClassVisitor cv) { + private final CoreLibraryRewriter rewriter; + + public ObjectsRequireNonNullMethodRewriter(ClassVisitor cv, CoreLibraryRewriter rewriter) { super(ASM6, cv); + this.rewriter = rewriter; } @Override @@ -40,7 +43,7 @@ public class ObjectsRequireNonNullMethodRewriter extends ClassVisitor { return visitor == null ? visitor : new ObjectsMethodInlinerMethodVisitor(visitor); } - private static class ObjectsMethodInlinerMethodVisitor extends MethodVisitor { + private class ObjectsMethodInlinerMethodVisitor extends MethodVisitor { public ObjectsMethodInlinerMethodVisitor(MethodVisitor mv) { super(ASM6, mv); @@ -48,20 +51,19 @@ public class ObjectsRequireNonNullMethodRewriter extends ClassVisitor { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - if (opcode != INVOKESTATIC - || !owner.equals("java/util/Objects") - || !name.equals("requireNonNull") - || !desc.equals("(Ljava/lang/Object;)Ljava/lang/Object;")) { + if (opcode == INVOKESTATIC + && rewriter.unprefix(owner).equals("java/util/Objects") + && name.equals("requireNonNull") + && desc.equals("(Ljava/lang/Object;)Ljava/lang/Object;")) { + // a call to Objects.requireNonNull(Object o) + // duplicate the first argument 'o', as this method returns 'o'. + super.visitInsn(DUP); + super.visitMethodInsn( + INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); + super.visitInsn(POP); + } else { super.visitMethodInsn(opcode, owner, name, desc, itf); - return; } - - // a call to Objects.requireNonNull(Object o) - // duplicate the first argument 'o', as this method returns 'o'. - super.visitInsn(DUP); - super.visitMethodInsn( - INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); - super.visitInsn(POP); } } } -- cgit v1.2.3