IG: simplify ExceptionUtils

This commit is contained in:
Bas Leijdekkers
2015-05-15 16:38:34 +02:00
parent 4ec8fcd9e0
commit 1a429ba900
4 changed files with 65 additions and 63 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -15,12 +15,13 @@
*/
package com.siyeh.ig.errorhandling;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.ExceptionUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -48,8 +49,8 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
@Override
@NotNull
protected String buildErrorString(Object... infos) {
final List<PsiClass> typesMasked = (List<PsiClass>)infos[0];
String typesMaskedString = typesMasked.get(0).getName();
final List<PsiType> typesMasked = (List<PsiType>)infos[0];
String typesMaskedString = typesMasked.get(0).getPresentableText();
if (typesMasked.size() == 1) {
return InspectionGadgetsBundle.message("too.broad.catch.problem.descriptor", typesMaskedString);
}
@@ -58,9 +59,9 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
final int lastTypeIndex = typesMasked.size() - 1;
for (int i = 1; i < lastTypeIndex; i++) {
typesMaskedString += ", ";
typesMaskedString += typesMasked.get(i).getName();
typesMaskedString += typesMasked.get(i).getPresentableText();
}
final String lastTypeString = typesMasked.get(lastTypeIndex).getName();
final String lastTypeString = typesMasked.get(lastTypeIndex).getPresentableText();
return InspectionGadgetsBundle.message("too.broad.catch.problem.descriptor1", typesMaskedString, lastTypeString);
}
}
@@ -79,7 +80,7 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
if (tryBlock == null) {
return;
}
final Set<PsiClassType> thrownTypes = ExceptionUtils.calculateExceptionsThrown(tryBlock);
final Set<PsiType> thrownTypes = ExceptionUtils.calculateExceptionsThrown(tryBlock);
final Set<PsiType> caughtTypes = new HashSet<PsiType>(thrownTypes.size());
final PsiCatchSection[] catchSections = statement.getCatchSections();
for (final PsiCatchSection catchSection : catchSections) {
@@ -92,7 +93,7 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
final PsiDisjunctionType disjunctionType = (PsiDisjunctionType)caughtType;
final List<PsiType> types = disjunctionType.getDisjunctions();
for (PsiType type : types) {
check(thrownTypes, caughtTypes, parameter, type);
check(thrownTypes, caughtTypes, parameter, type, statement.getProject());
}
}
else {
@@ -102,19 +103,19 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
if (typeElement == null) {
continue;
}
final PsiClass runtimeExceptionClass = ClassUtils.findClass(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, parameter);
registerError(typeElement, Collections.singletonList(runtimeExceptionClass), typeElement);
final PsiClassType runtimeExceptionType = TypeUtils.getType(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, parameter);
registerError(typeElement, Collections.singletonList(runtimeExceptionType), typeElement, statement.getProject());
}
}
else {
check(thrownTypes, caughtTypes, parameter, caughtType);
check(thrownTypes, caughtTypes, parameter, caughtType, statement.getProject());
}
}
}
}
private void check(Set<PsiClassType> thrownTypes, Set<PsiType> caughtTypes, PsiParameter parameter, PsiType caughtType) {
final List<PsiClass> maskedExceptions = findMaskedExceptions(thrownTypes, caughtTypes, caughtType);
private void check(Set<PsiType> thrownTypes, Set<PsiType> caughtTypes, PsiParameter parameter, PsiType caughtType, Project project) {
final List<PsiType> maskedExceptions = findMaskedExceptions(thrownTypes, caughtTypes, caughtType);
if (maskedExceptions.isEmpty()) {
return;
}
@@ -122,10 +123,10 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
if (typeElement == null) {
return;
}
registerError(typeElement, maskedExceptions, typeElement);
registerError(typeElement, maskedExceptions, typeElement, project);
}
private List<PsiClass> findMaskedExceptions(Set<PsiClassType> thrownTypes, Set<PsiType> caughtTypes, PsiType caughtType) {
private List<PsiType> findMaskedExceptions(Set<PsiType> thrownTypes, Set<PsiType> caughtTypes, PsiType caughtType) {
if (thrownTypes.contains(caughtType)) {
if (ignoreThrown) {
return Collections.emptyList();
@@ -138,14 +139,11 @@ public class TooBroadCatchInspectionBase extends BaseInspection {
return Collections.emptyList();
}
}
final List<PsiClass> maskedTypes = new ArrayList();
for (PsiClassType typeThrown : thrownTypes) {
final List<PsiType> maskedTypes = new ArrayList<PsiType>();
for (PsiType typeThrown : thrownTypes) {
if (!caughtTypes.contains(typeThrown) && caughtType.isAssignableFrom(typeThrown)) {
caughtTypes.add(typeThrown);
final PsiClass aClass = typeThrown.resolve();
if (aClass != null) {
maskedTypes.add(aClass);
}
maskedTypes.add(typeThrown);
}
}
return maskedTypes;
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 Bas Leijdekkers
* Copyright 2010-2015 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -175,9 +175,9 @@ public class TooBroadThrowsInspectionBase extends BaseInspection {
if (ignoreLibraryOverrides && LibraryUtil.isOverrideOfLibraryMethod(method)) {
return;
}
final Set<PsiClassType> exceptionsThrown = ExceptionUtils.calculateExceptionsThrown(body);
final Set<PsiType> exceptionsThrown = ExceptionUtils.calculateExceptionsThrown(body);
final PsiClassType[] referencedExceptions = throwsList.getReferencedTypes();
final Set<PsiClassType> exceptionsDeclared = new HashSet(referencedExceptions.length);
final Set<PsiType> exceptionsDeclared = new HashSet<PsiType>(referencedExceptions.length);
ContainerUtil.addAll(exceptionsDeclared, referencedExceptions);
final int referencedExceptionsLength = referencedExceptions.length;
for (int i = 0; i < referencedExceptionsLength; i++) {
@@ -188,9 +188,9 @@ public class TooBroadThrowsInspectionBase extends BaseInspection {
continue;
}
}
final List<SmartTypePointer> exceptionsMasked = new ArrayList();
final List<SmartTypePointer> exceptionsMasked = new ArrayList<SmartTypePointer>();
final SmartTypePointerManager pointerManager = SmartTypePointerManager.getInstance(body.getProject());
for (PsiClassType exceptionThrown : exceptionsThrown) {
for (PsiType exceptionThrown : exceptionsThrown) {
if (referencedException.isAssignableFrom(exceptionThrown) && !exceptionsDeclared.contains(exceptionThrown)) {
exceptionsMasked.add(pointerManager.createSmartTypePointer(exceptionThrown));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,10 +38,16 @@ public class ExceptionUtils {
}
@NotNull
public static Set<PsiClassType> calculateExceptionsThrown(@NotNull PsiElement element) {
final ExceptionsThrownVisitor visitor = new ExceptionsThrownVisitor();
public static Set<PsiType> calculateExceptionsThrown(@Nullable PsiElement element) {
return calculateExceptionsThrown(element, new HashSet<PsiType>());
}
@NotNull
public static Set<PsiType> calculateExceptionsThrown(@Nullable PsiElement element, @NotNull Set<PsiType> out) {
if (element == null) return out;
final ExceptionsThrownVisitor visitor = new ExceptionsThrownVisitor(out);
element.accept(visitor);
return visitor.getExceptionsThrown();
return out;
}
public static boolean isGenericExceptionClass(@Nullable PsiType exceptionType) {
@@ -195,7 +201,11 @@ public class ExceptionUtils {
private static class ExceptionsThrownVisitor extends JavaRecursiveElementVisitor {
private final Set<PsiClassType> m_exceptionsThrown = new HashSet(4);
private final Set<PsiType> m_exceptionsThrown;
public ExceptionsThrownVisitor(Set<PsiType> thrownTypes) {
m_exceptionsThrown = thrownTypes;
}
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
@@ -218,11 +228,7 @@ public class ExceptionUtils {
if (exception == null) {
return;
}
final PsiType type = exception.getType();
if (!(type instanceof PsiClassType)) {
return;
}
m_exceptionsThrown.add((PsiClassType)type);
m_exceptionsThrown.add(exception.getType());
}
@Override
@@ -232,9 +238,9 @@ public class ExceptionUtils {
if (resourceList != null) {
final List<PsiResourceVariable> resourceVariables = resourceList.getResourceVariables();
for (PsiResourceVariable resourceVariable : resourceVariables) {
final Set<PsiClassType> resourceExceptions = calculateExceptionsThrown(resourceVariable);
final Set<PsiType> resourceExceptions = calculateExceptionsThrown(resourceVariable);
collectExceptionsThrown(PsiUtil.getResourceCloserMethod(resourceVariable), resourceExceptions);
for (PsiClassType resourceException : resourceExceptions) {
for (PsiType resourceException : resourceExceptions) {
if (!isExceptionHandled(exceptionsHandled, resourceException)) {
m_exceptionsThrown.add(resourceException);
}
@@ -243,8 +249,8 @@ public class ExceptionUtils {
}
final PsiCodeBlock tryBlock = statement.getTryBlock();
if (tryBlock != null) {
final Set<PsiClassType> tryExceptions = calculateExceptionsThrown(tryBlock);
for (PsiClassType tryException : tryExceptions) {
final Set<PsiType> tryExceptions = calculateExceptionsThrown(tryBlock);
for (PsiType tryException : tryExceptions) {
if (!isExceptionHandled(exceptionsHandled, tryException)) {
m_exceptionsThrown.add(tryException);
}
@@ -252,18 +258,18 @@ public class ExceptionUtils {
}
final PsiCodeBlock finallyBlock = statement.getFinallyBlock();
if (finallyBlock != null) {
final Set<PsiClassType> finallyExceptions = calculateExceptionsThrown(finallyBlock);
final Set<PsiType> finallyExceptions = calculateExceptionsThrown(finallyBlock);
m_exceptionsThrown.addAll(finallyExceptions);
}
final PsiCodeBlock[] catchBlocks = statement.getCatchBlocks();
for (PsiCodeBlock catchBlock : catchBlocks) {
final Set<PsiClassType> catchExceptions = calculateExceptionsThrown(catchBlock);
final Set<PsiType> catchExceptions = calculateExceptionsThrown(catchBlock);
m_exceptionsThrown.addAll(catchExceptions);
}
}
private static void collectExceptionsThrown(@Nullable PsiMethod method, @NotNull Set<PsiClassType> out) {
private static void collectExceptionsThrown(@Nullable PsiMethod method, @NotNull Set<PsiType> out) {
if (method == null) {
return;
}
@@ -295,10 +301,5 @@ public class ExceptionUtils {
}
return out;
}
@NotNull
public Set<PsiClassType> getExceptionsThrown() {
return m_exceptionsThrown;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,14 +41,17 @@ public class TooBroadCatchInspection extends TooBroadCatchInspectionBase {
@NotNull
@Override
protected InspectionGadgetsFix[] buildFixes(Object... infos) {
final List<PsiClass> maskedTypes = (List<PsiClass>)infos[0];
final List<InspectionGadgetsFix> fixes = new ArrayList();
for (PsiClass thrown : maskedTypes) {
if (CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION.equals(maskedTypes.get(0).getQualifiedName())) {
final Project project = (Project)infos[2];
final SmartTypePointerManager pointerManager = SmartTypePointerManager.getInstance(project);
final List<PsiType> maskedTypes = (List<PsiType>)infos[0];
final List<InspectionGadgetsFix> fixes = new ArrayList<InspectionGadgetsFix>();
for (PsiType thrown : maskedTypes) {
final String typeText = thrown.getCanonicalText();
if (CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION.equals(typeText)) {
fixes.add(new ReplaceWithRuntimeExceptionFix());
}
else {
fixes.add(new AddCatchSectionFix(thrown));
fixes.add(new AddCatchSectionFix(pointerManager.createSmartTypePointer(thrown), typeText));
}
}
final PsiElement context = (PsiElement)infos[1];
@@ -96,12 +99,12 @@ public class TooBroadCatchInspection extends TooBroadCatchInspectionBase {
private static class AddCatchSectionFix extends InspectionGadgetsFix {
private final SmartPsiElementPointer<PsiClass> myThrown;
private final SmartTypePointer myThrown;
private final String myText;
AddCatchSectionFix(PsiClass thrown) {
myThrown = SmartPointerManager.getInstance(thrown.getProject()).createSmartPsiElementPointer(thrown);
myText = thrown.getName();
AddCatchSectionFix(SmartTypePointer thrown, String typeText) {
myThrown = thrown;
myText = typeText;
}
@Override
@@ -118,6 +121,10 @@ public class TooBroadCatchInspection extends TooBroadCatchInspectionBase {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiType thrownType = myThrown.getType();
if (thrownType == null) {
return;
}
final PsiElement typeElement = descriptor.getPsiElement();
if (typeElement == null) {
return;
@@ -135,11 +142,7 @@ public class TooBroadCatchInspection extends TooBroadCatchInspectionBase {
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
final String name = codeStyleManager.suggestUniqueVariableName("e", myTryStatement.getTryBlock(), false);
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
final PsiClass aClass = myThrown.getElement();
if (aClass == null) {
return;
}
final PsiCatchSection section = factory.createCatchSection(factory.createType(aClass), name, myTryStatement);
final PsiCatchSection section = factory.createCatchSection(thrownType, name, myTryStatement);
final PsiCatchSection element = (PsiCatchSection)myTryStatement.addBefore(section, myBeforeCatchSection);
codeStyleManager.shortenClassReferences(element);