mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IG: handle try resource lists correctly in "Overly broad 'catch' block" inspection
This commit is contained in:
+1
@@ -81,6 +81,7 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
final Set<PsiType> thrownTypes = ExceptionUtils.calculateExceptionsThrown(tryBlock);
|
||||
ExceptionUtils.calculateExceptionsThrown(statement.getResourceList(), thrownTypes);
|
||||
final Set<PsiType> caughtTypes = new HashSet<PsiType>(thrownTypes.size());
|
||||
final PsiCatchSection[] catchSections = statement.getCatchSections();
|
||||
for (final PsiCatchSection catchSection : catchSections) {
|
||||
|
||||
+34
-46
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ExceptionUtils {
|
||||
@@ -39,12 +39,19 @@ public class ExceptionUtils {
|
||||
|
||||
@NotNull
|
||||
public static Set<PsiType> calculateExceptionsThrown(@Nullable PsiElement element) {
|
||||
return calculateExceptionsThrown(element, new HashSet<PsiType>());
|
||||
return calculateExceptionsThrown(element, new LinkedHashSet<PsiType>(5));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<PsiType> calculateExceptionsThrown(@Nullable PsiElement element, @NotNull Set<PsiType> out) {
|
||||
if (element == null) return out;
|
||||
if (element instanceof PsiResourceList) {
|
||||
final PsiResourceList resourceList = (PsiResourceList)element;
|
||||
for (PsiResourceVariable variable : resourceList.getResourceVariables()) {
|
||||
final PsiMethod method = PsiUtil.getResourceCloserMethod(variable);
|
||||
collectExceptionsThrown(method, out);
|
||||
}
|
||||
}
|
||||
final ExceptionsThrownVisitor visitor = new ExceptionsThrownVisitor(out);
|
||||
element.accept(visitor);
|
||||
return out;
|
||||
@@ -199,6 +206,19 @@ public class ExceptionUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void collectExceptionsThrown(@Nullable PsiMethod method, @NotNull Set<PsiType> out) {
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
|
||||
for (PsiJavaCodeReferenceElement referenceElement : method.getThrowsList().getReferenceElements()) {
|
||||
final PsiClass exceptionClass = (PsiClass)referenceElement.resolve();
|
||||
if (exceptionClass != null) {
|
||||
out.add(factory.createType(exceptionClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ExceptionsThrownVisitor extends JavaRecursiveElementVisitor {
|
||||
|
||||
private final Set<PsiType> m_exceptionsThrown;
|
||||
@@ -234,53 +254,21 @@ public class ExceptionUtils {
|
||||
@Override
|
||||
public void visitTryStatement(@NotNull PsiTryStatement statement) {
|
||||
final Set<PsiType> exceptionsHandled = getExceptionTypesHandled(statement);
|
||||
final PsiResourceList resourceList = statement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
final List<PsiResourceVariable> resourceVariables = resourceList.getResourceVariables();
|
||||
for (PsiResourceVariable resourceVariable : resourceVariables) {
|
||||
final Set<PsiType> resourceExceptions = calculateExceptionsThrown(resourceVariable);
|
||||
collectExceptionsThrown(PsiUtil.getResourceCloserMethod(resourceVariable), resourceExceptions);
|
||||
for (PsiType resourceException : resourceExceptions) {
|
||||
if (!isExceptionHandled(exceptionsHandled, resourceException)) {
|
||||
m_exceptionsThrown.add(resourceException);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiCodeBlock tryBlock = statement.getTryBlock();
|
||||
if (tryBlock != null) {
|
||||
final Set<PsiType> tryExceptions = calculateExceptionsThrown(tryBlock);
|
||||
for (PsiType tryException : tryExceptions) {
|
||||
if (!isExceptionHandled(exceptionsHandled, tryException)) {
|
||||
m_exceptionsThrown.add(tryException);
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiCodeBlock finallyBlock = statement.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
final Set<PsiType> finallyExceptions = calculateExceptionsThrown(finallyBlock);
|
||||
m_exceptionsThrown.addAll(finallyExceptions);
|
||||
}
|
||||
|
||||
final PsiCodeBlock[] catchBlocks = statement.getCatchBlocks();
|
||||
for (PsiCodeBlock catchBlock : catchBlocks) {
|
||||
final Set<PsiType> catchExceptions = calculateExceptionsThrown(catchBlock);
|
||||
m_exceptionsThrown.addAll(catchExceptions);
|
||||
}
|
||||
}
|
||||
|
||||
private static void collectExceptionsThrown(@Nullable PsiMethod method, @NotNull Set<PsiType> out) {
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
|
||||
final PsiJavaCodeReferenceElement[] referenceElements = method.getThrowsList().getReferenceElements();
|
||||
for (PsiJavaCodeReferenceElement referenceElement : referenceElements) {
|
||||
final PsiClass exceptionClass = (PsiClass)referenceElement.resolve();
|
||||
if (exceptionClass != null) {
|
||||
out.add(factory.createType(exceptionClass));
|
||||
for (PsiType resourceException : calculateExceptionsThrown(statement.getResourceList())) {
|
||||
if (!isExceptionHandled(exceptionsHandled, resourceException)) {
|
||||
m_exceptionsThrown.add(resourceException);
|
||||
}
|
||||
}
|
||||
for (PsiType tryException : calculateExceptionsThrown(statement.getTryBlock())) {
|
||||
if (!isExceptionHandled(exceptionsHandled, tryException)) {
|
||||
m_exceptionsThrown.add(tryException);
|
||||
}
|
||||
}
|
||||
calculateExceptionsThrown(statement.getFinallyBlock(), m_exceptionsThrown);
|
||||
for (PsiCodeBlock catchBlock : statement.getCatchBlocks()) {
|
||||
calculateExceptionsThrown(catchBlock, m_exceptionsThrown);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isExceptionHandled(Iterable<PsiType> exceptionsHandled, PsiType thrownType) {
|
||||
|
||||
+3
@@ -61,6 +61,9 @@ public class TooBroadCatchBlock{
|
||||
try {
|
||||
try (java.io.FileInputStream in = new java.io.FileInputStream("asdf")) {}
|
||||
} catch (<warning descr="'catch' of 'IOException' is too broad, masking exception 'FileNotFoundException'">IOException</warning> e) {}
|
||||
try (java.io.InputStream in = new java.io.FileInputStream("")) {
|
||||
|
||||
} catch (<warning descr="'catch' of 'Exception' is too broad, masking exceptions 'IOException' and 'FileNotFoundException'">Exception</warning> e) {}
|
||||
}
|
||||
|
||||
boolean m() {
|
||||
|
||||
Reference in New Issue
Block a user