summaryrefslogtreecommitdiff
path: root/java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java')
-rw-r--r--java/com/google/devtools/build/android/desugar/TryWithResourcesRewriter.java46
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);