AddExceptionToExistingCatch: do not suggest catches if its successors are assignable to exception type: IDEA-208457

This commit is contained in:
Roman.Ivanov
2019-04-02 16:09:56 +07:00
parent 4b33365be7
commit 5c55f93cd1
5 changed files with 24 additions and 44 deletions

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
@@ -16,7 +17,6 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.IntroduceTargetChooser;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,15 +38,13 @@ public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionActio
Context context = Context.from(myErrorElement);
if (context == null) return;
List<PsiCatchSection> catchSections = context.myCatches;
List<PsiClassType> unhandledExceptions = context.myExceptions;
List<PsiCatchSection> catches =
ContainerUtil.filter(catchSections, s -> s.getCatchType() != null && s.getParameter() != null);
List<PsiCatchSection> catches = context.myCatches;
setText(context.getMessage());
if (catchSections.size() == 1) {
PsiCatchSection selectedSection = catchSections.get(0);
if (catches.size() == 1) {
PsiCatchSection selectedSection = catches.get(0);
addTypeToCatch(unhandledExceptions, selectedSection);
}
else {
@@ -65,6 +63,22 @@ public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionActio
);
}
}
private static List<PsiCatchSection> findSuitableSections(List<PsiCatchSection> sections, @NotNull List<PsiClassType> exceptionTypes) {
List<PsiCatchSection> finalSections = new ArrayList<>();
for (PsiCatchSection section : Lists.reverse(sections)) {
finalSections.add(section);
PsiType sectionType = section.getCatchType();
if (sectionType == null) continue;
for (PsiType exceptionType : exceptionTypes) {
if (exceptionType.isAssignableFrom(exceptionType)) {
return finalSections;
// adding type to any upper leads to compilation error
}
}
}
return finalSections;
}
private static void addTypeToCatch(@NotNull List<PsiClassType> exceptionsToAdd, @NotNull PsiCatchSection catchSection) {
Project project = catchSection.getProject();
@@ -132,7 +146,7 @@ public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionActio
List<PsiTryStatement> tryStatements = getTryStatements(element);
List<PsiCatchSection> sections =
tryStatements.stream()
.flatMap(stmt -> Arrays.stream(stmt.getCatchSections()))
.flatMap(stmt -> findSuitableSections(Arrays.asList(stmt.getCatchSections()), unhandledExceptions).stream())
.filter(catchSection -> {
PsiParameter parameter = catchSection.getParameter();
if (parameter == null) return false;

View File

@@ -1,10 +1,9 @@
// "Add exception to existing catch clause" "true"
import java.io.IOException;
import java.io.Exception;
class A extends Exception {}
class B extends A {}
class C extends A {}
class Test {
public static void main(String[] args) {
try {

View File

@@ -1,16 +0,0 @@
// "Add exception to existing catch clause" "true"
import java.io.IOException;
class A extends Exception {}
class B extends A {}
class C extends A {}
class Test {
public static void main(String[] args) {
try {
throw new A();
} catch (A e) {
} catch (C e) {
}
}
}

View File

@@ -1,14 +1,13 @@
// "Add exception to existing catch clause" "true"
import java.io.IOException;
import java.io.Exception;
class A extends Exception {}
class B extends A {}
class C extends A {}
class Test {
public static void main(String[] args) {
try {
throw new A<caret>();
throw<caret> new A();
} catch (B e) {
} catch (C e) {
}

View File

@@ -1,16 +0,0 @@
// "Add exception to existing catch clause" "true"
import java.io.IOException;
class A extends Exception {}
class B extends A {}
class C extends A {}
class Test {
public static void main(String[] args) {
try {
throw new A<caret>();
} catch (B e) {
} catch (C e) {
}
}
}