mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-90606 Smart completion misses exception from try-with-resources
This commit is contained in:
@@ -102,55 +102,64 @@ public class ExceptionUtil {
|
||||
return classTypes;
|
||||
}
|
||||
else if (element instanceof PsiTryStatement) {
|
||||
PsiTryStatement tryStatement = (PsiTryStatement)element;
|
||||
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
List<PsiClassType> array = new ArrayList<PsiClassType>();
|
||||
if (tryBlock != null) {
|
||||
List<PsiClassType> exceptions = getThrownExceptions(tryBlock);
|
||||
array.addAll(exceptions);
|
||||
}
|
||||
|
||||
PsiParameter[] parameters = tryStatement.getCatchBlockParameters();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
PsiType exception = parameter.getType();
|
||||
for (int j = array.size() - 1; j >= 0; j--) {
|
||||
PsiClassType exception1 = array.get(j);
|
||||
if (exception.isAssignableFrom(exception1)) {
|
||||
array.remove(exception1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks();
|
||||
for (PsiCodeBlock catchBlock : catchBlocks) {
|
||||
addExceptions(array, getThrownExceptions(catchBlock));
|
||||
}
|
||||
|
||||
PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
// if finally block completes normally, exception not caught
|
||||
// if finally block completes abruptly, exception gets lost
|
||||
try {
|
||||
ControlFlow flow = ControlFlowFactory.getInstance(finallyBlock.getProject()).getControlFlow(finallyBlock, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false);
|
||||
int completionReasons = ControlFlowUtil.getCompletionReasons(flow, 0, flow.getSize());
|
||||
List<PsiClassType> thrownExceptions = getThrownExceptions(finallyBlock);
|
||||
if ((completionReasons & ControlFlowUtil.NORMAL_COMPLETION_REASON) == 0) {
|
||||
array = new ArrayList<PsiClassType>(thrownExceptions);
|
||||
}
|
||||
else {
|
||||
addExceptions(array, thrownExceptions);
|
||||
}
|
||||
}
|
||||
catch (AnalysisCanceledException e) {
|
||||
// incomplete code
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
return getTryExceptions((PsiTryStatement)element);
|
||||
}
|
||||
return getThrownExceptions(element.getChildren());
|
||||
}
|
||||
|
||||
private static List<PsiClassType> getTryExceptions(PsiTryStatement tryStatement) {
|
||||
List<PsiClassType> array = new ArrayList<PsiClassType>();
|
||||
|
||||
PsiResourceList resourceList = tryStatement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
for (PsiResourceVariable variable : resourceList.getResourceVariables()) {
|
||||
array.addAll(getUnhandledCloserExceptions(variable, resourceList));
|
||||
}
|
||||
}
|
||||
|
||||
PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
if (tryBlock != null) {
|
||||
array.addAll(getThrownExceptions(tryBlock));
|
||||
}
|
||||
|
||||
for (PsiParameter parameter : tryStatement.getCatchBlockParameters()) {
|
||||
PsiType exception = parameter.getType();
|
||||
for (int j = array.size() - 1; j >= 0; j--) {
|
||||
PsiClassType exception1 = array.get(j);
|
||||
if (exception.isAssignableFrom(exception1)) {
|
||||
array.remove(exception1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiCodeBlock catchBlock : tryStatement.getCatchBlocks()) {
|
||||
addExceptions(array, getThrownExceptions(catchBlock));
|
||||
}
|
||||
|
||||
PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
// if finally block completes normally, exception not caught
|
||||
// if finally block completes abruptly, exception gets lost
|
||||
try {
|
||||
ControlFlow flow = ControlFlowFactory
|
||||
.getInstance(finallyBlock.getProject()).getControlFlow(finallyBlock, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false);
|
||||
int completionReasons = ControlFlowUtil.getCompletionReasons(flow, 0, flow.getSize());
|
||||
List<PsiClassType> thrownExceptions = getThrownExceptions(finallyBlock);
|
||||
if ((completionReasons & ControlFlowUtil.NORMAL_COMPLETION_REASON) == 0) {
|
||||
array = new ArrayList<PsiClassType>(thrownExceptions);
|
||||
}
|
||||
else {
|
||||
addExceptions(array, thrownExceptions);
|
||||
}
|
||||
}
|
||||
catch (AnalysisCanceledException e) {
|
||||
// incomplete code
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiClassType> getExceptionsByMethodAndChildren(PsiElement element, JavaResolveResult resolveResult) {
|
||||
PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
class Test {
|
||||
void foo() {
|
||||
try {
|
||||
try (FileInputStream in = new FileInputStream("adsf")) {
|
||||
}
|
||||
} catch (IOException <caret>) {}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import java.io.FileInputStream;
|
||||
|
||||
class Test {
|
||||
void foo() {
|
||||
try {
|
||||
try (FileInputStream in = new FileInputStream("adsf")) {
|
||||
}
|
||||
} catch (IO<caret>) {}
|
||||
}
|
||||
}
|
||||
+2
@@ -60,6 +60,8 @@ public class SmartType17CompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
public void testTryWithResourcesNoSemicolon() { doTest(); }
|
||||
|
||||
public void testTryWithResourcesThrowsException() { doTest(); }
|
||||
|
||||
public void testDiamondPresentation() {
|
||||
configureByFile("/" + getTestName(false) + ".java");
|
||||
LookupElementPresentation presentation = new LookupElementPresentation();
|
||||
|
||||
Reference in New Issue
Block a user