Multi-catch support: more highlighting

This commit is contained in:
Roman Shevchenko
2011-02-19 14:48:41 +01:00
parent 85f277a149
commit f2184f3f50
6 changed files with 52 additions and 15 deletions
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.analysis;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
@@ -852,7 +853,7 @@ public class HighlightUtil {
@Nullable
static HighlightInfo checkExceptionThrownInTry(final PsiParameter parameter) {
static Collection<HighlightInfo> checkExceptionThrownInTry(final PsiParameter parameter) {
final PsiElement declarationScope = parameter.getDeclarationScope();
if (!(declarationScope instanceof PsiCatchSection)) return null;
@@ -882,9 +883,9 @@ public class HighlightUtil {
}
@Nullable
private static HighlightInfo checkSimpleCatchParameter(final PsiParameter parameter,
final Collection<PsiClassType> thrownTypes,
final PsiClassType caughtType) {
private static Collection<HighlightInfo> checkSimpleCatchParameter(final PsiParameter parameter,
final Collection<PsiClassType> thrownTypes,
final PsiClassType caughtType) {
if (ExceptionUtil.isUncheckedExceptionOrSuperclass(caughtType)) return null;
for (PsiClassType exceptionType : thrownTypes) {
@@ -894,12 +895,17 @@ public class HighlightUtil {
final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(caughtType));
final HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, parameter, description);
QuickFixAction.registerQuickFixAction(errorResult, new DeleteCatchFix(parameter));
return errorResult;
return Lists.newArrayList(errorResult);
}
@Nullable
private static HighlightInfo checkMultiCatchParameter(final PsiParameter parameter, final Collection<PsiClassType> thrownTypes) {
for (PsiTypeElement typeElement : PsiTreeUtil.getChildrenOfTypeAsList(parameter.getTypeElement(), PsiTypeElement.class)) {
private static Collection<HighlightInfo> checkMultiCatchParameter(final PsiParameter parameter,
final Collection<PsiClassType> thrownTypes) {
final List<PsiTypeElement> typeElements = PsiTreeUtil.getChildrenOfTypeAsList(parameter.getTypeElement(), PsiTypeElement.class);
final Collection<HighlightInfo> highlights = Lists.newArrayListWithCapacity(typeElements.size());
for (int i = 0, size = typeElements.size(); i < size; i++) {
final PsiTypeElement typeElement = typeElements.get(i);
final PsiType catchType = typeElement.getType();
if (catchType instanceof PsiClassType && ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)catchType)) continue;
@@ -910,15 +916,28 @@ public class HighlightUtil {
break;
}
}
if (used) continue;
if (!used) {
final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(catchType));
final HighlightInfo highlight = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, description);
QuickFixAction.registerQuickFixAction(highlight, new DeleteMultiCatchFix(typeElement));
highlights.add(highlight);
continue;
}
final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(catchType));
final HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, description);
QuickFixAction.registerQuickFixAction(errorResult, new DeleteMultiCatchFix(typeElement));
return errorResult;
for (int j = size - 1; j > i; j--) {
final PsiTypeElement nextElement = typeElements.get(j);
final PsiType nextType = nextElement.getType();
if (nextType.isAssignableFrom(catchType)) {
final String description = JavaErrorMessages.message("exception.double.caught.in.multi", formatType(catchType), formatType(nextType));
final HighlightInfo highlight = HighlightInfo.createHighlightInfo(HighlightInfoType.WARNING, typeElement, description);
QuickFixAction.registerQuickFixAction(highlight, new DeleteMultiCatchFix(typeElement));
highlights.add(highlight);
break;
}
}
}
return null;
return highlights;
}
@@ -899,7 +899,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) {
PsiParameter[] parameters = statement.getCatchBlockParameters();
for (PsiParameter parameter : parameters) {
myHolder.add(HighlightUtil.checkExceptionThrownInTry(parameter));
myHolder.addAll(HighlightUtil.checkExceptionThrownInTry(parameter));
myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter));
myHolder.add(GenericsHighlightUtil.checkCatchParameterIsClass(parameter));
}
@@ -4,6 +4,7 @@ abstract class C {
private static class E1 extends E { }
private static class E2 extends E { }
private static class E3 extends E { }
private static class E4 extends E { }
private static class RE extends RuntimeException { }
private interface I<T> { }
private static class IE1 extends E implements I<Integer> { }
@@ -23,7 +24,7 @@ abstract class C {
try { g(); } catch (IE1 | IE2 e) { new F<I<? extends Number>>(e); }
try { f(); } catch (E1 | E2 | <error descr="Exception 'C.E3' is never thrown in the corresponding try block">E3</error> e) { }
try { f(); } catch (<error descr="Exception 'C.E3' is never thrown in the corresponding try block">E3</error> | E e) { }
try { f(); } catch (<error descr="Exception 'C.E3' is never thrown in the corresponding try block">E3</error> | <error descr="Exception 'C.E4' is never thrown in the corresponding try block">E4</error> | E e) { }
try { f(); } catch (E | <error descr="Exception 'C.E1' has already been caught">E1</error> e) { }
try { f(); } catch (E | <error descr="Exception 'C.E3' has already been caught">E3</error> e) { }
@@ -0,0 +1,12 @@
abstract class C {
private static class E extends Exception { }
private static class E1 extends E { }
private static class E2 extends E { }
abstract void f() throws E1, E2;
void m() {
try { f(); } catch (E1 | E2 ignore) { }
try { f(); } catch (<warning descr="Exception 'C.E1' is also caught by 'C.E'">E1</warning> | E ignore) { }
}
}
@@ -154,6 +154,10 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
doTest(false, false);
}
public void testMultiCatchWarn() throws Exception {
doTest(true, false);
}
public void testTryWithResources() throws Exception {
doTest(false, false);
}