diff options
author | cnsun <cnsun@google.com> | 2018-01-05 11:10:25 -0800 |
---|---|---|
committer | Ivan Gavrilovic <gavra@google.com> | 2018-05-04 10:36:46 +0100 |
commit | 45383a982f296015a233fdb5ffa46fad9e0ae245 (patch) | |
tree | eabf3b8d4558642be72fc3d82dd973b02c90c1e7 /java | |
parent | c1733d1549fe715c9915ae7cabebc717058313da (diff) | |
download | desugar-45383a982f296015a233fdb5ffa46fad9e0ae245.tar.gz |
Relax the assertion on the inferred resource type. Now we only require that the
resource type should have a (public) close() method.
The old version requires the resource type implements AutoCloseable. When the classpath provided to Desugar has some problems, the resource type may not implement AutoCloseable, though it has the close() method.
RELNOTES:n/a.
PiperOrigin-RevId: 180950815
GitOrigin-RevId: 7bde688a21b781caa666fe2bebe4482cf987270b
Change-Id: Id0a03911e12f903ce62fec72317a7dbc8d311287
Diffstat (limited to 'java')
-rw-r--r-- | java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java b/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java index 8e6d6d5..e8509e7 100644 --- a/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java +++ b/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java @@ -311,18 +311,20 @@ public class TryWithResourcesRewriter extends ClassVisitor { InferredType resourceType = typeInference.getTypeOfOperandFromTop(0); Optional<String> resourceClassInternalName = resourceType.getInternalName(); - checkState( - resourceClassInternalName.isPresent(), - "The resource class %s is not a reference type in %s.%s", - resourceType, - internalName, - methodSignature); - checkState( - isAssignableFrom( - "java.lang.AutoCloseable", resourceClassInternalName.get().replace('/', '.')), - "The resource type should be a subclass of java.lang.AutoCloseable: %s", - resourceClassInternalName); - + { + // Check the resource type. + checkState( + resourceClassInternalName.isPresent(), + "The resource class %s is not a reference type in %s.%s", + resourceType, + internalName, + methodSignature); + String resourceClassName = resourceClassInternalName.get().replace('/', '.'); + checkState( + hasCloseMethod(resourceClassName), + "The resource class %s should have a close() method.", + resourceClassName); + } resourceTypeInternalNames.add(resourceClassInternalName.get()); super.visitMethodInsn( opcode, @@ -356,6 +358,26 @@ public class TryWithResourcesRewriter extends ClassVisitor { return isAssignableFrom("java.lang.Throwable", owner.replace('/', '.')); } + private boolean hasCloseMethod(String resourceClassName) { + try { + Class<?> klass = classLoader.loadClass(resourceClassName); + klass.getMethod("close"); + return true; + } catch (ClassNotFoundException e) { + throw new AssertionError( + "Failed to load class " + + resourceClassName + + " when desugaring method " + + internalName + + "." + + methodSignature, + e); + } catch (NoSuchMethodException e) { + // There is no close() method in the class, so return false. + return false; + } + } + private boolean isAssignableFrom(String baseClassName, String subClassName) { try { Class<?> baseClass = classLoader.loadClass(baseClassName); |