lambda: catch exception by SAM method substitution (IDEA-116441)

(cherry picked from commit 0bce39590bdcc6e6a74c0dcedbb02add3333e685)
This commit is contained in:
anna
2013-11-15 17:11:10 +01:00
parent 79c9afb33c
commit f7fd8525b9
3 changed files with 43 additions and 4 deletions

View File

@@ -670,9 +670,10 @@ public class ExceptionUtil {
private static boolean isDeclaredBySAMMethod(@NotNull PsiClassType exceptionType, @Nullable PsiType interfaceType) {
if (interfaceType != null) {
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(interfaceType);
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (interfaceMethod != null) {
return isHandledByMethodThrowsClause(interfaceMethod, exceptionType);
return isHandledByMethodThrowsClause(interfaceMethod, exceptionType, LambdaUtil.getSubstitutor(interfaceMethod, resolveResult));
}
}
return true;
@@ -718,13 +719,26 @@ public class ExceptionUtil {
}
private static boolean isHandledByMethodThrowsClause(@NotNull PsiMethod method, @NotNull PsiClassType exceptionType) {
return isHandledByMethodThrowsClause(method, exceptionType, PsiSubstitutor.EMPTY);
}
private static boolean isHandledByMethodThrowsClause(@NotNull PsiMethod method,
@NotNull PsiClassType exceptionType,
PsiSubstitutor substitutor) {
final PsiClassType[] referencedTypes = method.getThrowsList().getReferencedTypes();
return isHandledBy(exceptionType, referencedTypes);
return isHandledBy(exceptionType, referencedTypes, substitutor);
}
public static boolean isHandledBy(@NotNull PsiClassType exceptionType, @NotNull PsiClassType[] referencedTypes) {
return isHandledBy(exceptionType, referencedTypes, PsiSubstitutor.EMPTY);
}
public static boolean isHandledBy(@NotNull PsiClassType exceptionType,
@NotNull PsiClassType[] referencedTypes,
PsiSubstitutor substitutor) {
for (PsiClassType classType : referencedTypes) {
if (classType.isAssignableFrom(exceptionType)) return true;
PsiType psiType = substitutor.substitute(classType);
if (psiType != null && psiType.isAssignableFrom(exceptionType)) return true;
}
return false;
}

View File

@@ -0,0 +1,21 @@
import java.io.IOException;
class Main48 {
public static void main(String[] args) throws Exception {
templateMethod(( ) -> {
throw new IOException();
});
}
static void templateMethod(RunnableWithException<IOException> r) {
try {
r.run();
} catch (IOException e) {
e.printStackTrace();
}
}
interface RunnableWithException<E extends Exception> {
void run() throws E;
}
}

View File

@@ -37,6 +37,10 @@ public class ExceptionVariablesInferenceTest extends LightDaemonAnalyzerTestCase
doTest();
}
public void testIDEA116441() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}