[java] connect resolution of generics in resource closer method (IDEA-150607)

This commit is contained in:
Roman Shevchenko
2016-01-20 12:43:56 +01:00
parent 88876357c6
commit d8b29b8401
2 changed files with 33 additions and 18 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.intellij.openapi.util.Pair.pair;
/**
* @author mike
*/
@@ -397,7 +399,7 @@ public class ExceptionUtil {
@Override
public void visitResourceVariable(@NotNull PsiResourceVariable resource) {
addExceptions(array, getUnhandledCloserExceptions((PsiResourceListElement)resource, null));
addExceptions(array, getUnhandledCloserExceptions(resource, null));
visitElement(resource);
}
@@ -531,28 +533,35 @@ public class ExceptionUtil {
@NotNull
public static List<PsiClassType> getCloserExceptions(@NotNull PsiResourceListElement resource) {
PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(resource.getType()).getSubstitutor();
return method != null ? getExceptionsByMethod(method, substitutor, resource) : Collections.<PsiClassType>emptyList();
}
/** @deprecated use {@link #getCloserExceptions(PsiResourceListElement)} (to be removed in IDEA 16) */
@SuppressWarnings("unused")
public static List<PsiClassType> getCloserExceptions(@NotNull PsiResourceVariable resource) {
return getCloserExceptions((PsiResourceListElement)resource);
Pair<PsiMethod, PsiSubstitutor> closer = resolveCloser(resource);
return closer != null ? getExceptionsByMethod(closer.first, closer.second, resource) : Collections.<PsiClassType>emptyList();
}
@NotNull
public static List<PsiClassType> getUnhandledCloserExceptions(@NotNull PsiResourceListElement resource, @Nullable PsiElement topElement) {
PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(resource.getType()).getSubstitutor();
return method != null ? getUnhandledExceptions(method, resource, topElement, substitutor) : Collections.<PsiClassType>emptyList();
Pair<PsiMethod, PsiSubstitutor> closer = resolveCloser(resource);
return closer != null ? getUnhandledExceptions(closer.first, resource, topElement, closer.second) : Collections.<PsiClassType>emptyList();
}
/** @deprecated use {@link #getUnhandledCloserExceptions(PsiResourceListElement, PsiElement)} (to be removed in IDEA 16) */
@SuppressWarnings("unused")
public static List<PsiClassType> getUnhandledCloserExceptions(@NotNull PsiResourceVariable resource, @Nullable PsiElement topElement) {
return getUnhandledCloserExceptions((PsiResourceListElement)resource, topElement);
private static Pair<PsiMethod, PsiSubstitutor> resolveCloser(PsiResourceListElement resource) {
PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
if (method != null) {
PsiClass closerClass = method.getContainingClass();
if (closerClass != null) {
PsiClassType.ClassResolveResult resourceType = PsiUtil.resolveGenericsClassInType(resource.getType());
if (resourceType != null) {
PsiClass resourceClass = resourceType.getElement();
if (resourceClass != null) {
PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(closerClass, resourceClass, resourceType.getSubstitutor());
if (substitutor != null) {
return pair(method, substitutor);
}
}
}
}
}
return null;
}
@NotNull
@@ -20,6 +20,8 @@ class C {
}
}
interface GenRT extends Gen<RuntimeException> { }
void m1() {
try (MyResource r = new MyResource()) { r.doSomething(); }
catch (E1 | E2 | E3 ignore) { }
@@ -87,4 +89,8 @@ class C {
void m5() {
try (<error descr="Unhandled exception from auto-closeable resource: C.E2">Gen<E2> gen = new Gen.Impl()</error>) { }
}
void m6() {
try (GenRT gen = null) { }
}
}