[java-completion] IJ-CR-129761 IDEA-349764 Suggest a full catch section

- tests are extracted
- CatchLookupElement works in dumb-mode

GitOrigin-RevId: 75b5c34ce124a4315a8a73c020ac08f01ecd9487
This commit is contained in:
Mikhail Pyltsin
2024-03-29 12:09:38 +00:00
committed by intellij-monorepo-bot
parent b478a4dc36
commit ba0a409500
27 changed files with 596 additions and 601 deletions
@@ -23,7 +23,7 @@ import static com.intellij.psi.CommonClassNames.*;
final class CatchLookupElement extends LookupItem<PsiCatchSection> {
private static final int MAX_LIMIT_SIZE = 300;
private static final int MAX_LIMIT_SIZE = 200;
private static final List<String> DEFAULT_EXCEPTIONS = List.of(JAVA_LANG_THROWABLE, JAVA_LANG_EXCEPTION, JAVA_LANG_RUNTIME_EXCEPTION);
private static final int MAX_LOOKUP_SIZE = 2;
@@ -67,7 +67,9 @@ final class CatchLookupElement extends LookupItem<PsiCatchSection> {
element = PsiTreeUtil.getParentOfType(element, PsiCatchSection.class, false);
if (element != null) {
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
codeStyleManager.shortenClassReferences(element);
PsiElement finalElement = element;
DumbService.getInstance(project)
.runWithAlternativeResolveEnabled(() -> codeStyleManager.shortenClassReferences(finalElement));
}
}
@@ -83,44 +85,46 @@ final class CatchLookupElement extends LookupItem<PsiCatchSection> {
return List.of();
}
Project project = tryStatement.getProject();
if (DumbService.isDumb(project)) {
return List.of();
}
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiStatement[] statements = block.getStatements();
PsiCatchSection[] sections = tryStatement.getCatchSections();
Set<PsiClass> existedExceptionClasses = new HashSet<>();
Set<PsiType> existedExceptionTypes = new HashSet<>();
List<String> stringExceptions = new ArrayList<>();
for (PsiCatchSection section : sections) {
PsiType catchType = section.getCatchType();
PsiClass existedException = PsiUtil.resolveClassInClassTypeOnly(catchType);
if (existedException != null) {
existedExceptionClasses.add(existedException);
}
existedExceptionTypes.add(catchType);
}
//if block is big enough, analyze can take a lot of time, let's use hardcoded exception
if (block.getTextLength() > MAX_LIMIT_SIZE || existedExceptionClasses.size() > MAX_LOOKUP_SIZE) {
stringExceptions = getHardcodedExceptions(existedExceptionClasses);
if (block.getTextLength() > MAX_LIMIT_SIZE || existedExceptionTypes.size() > MAX_LOOKUP_SIZE) {
stringExceptions.addAll(getHardcodedExceptions(existedExceptionTypes));
}
else {
List<PsiClassType> exceptionTypes = getUnhandledExceptionTypes(statements);
if (exceptionTypes.size() <= MAX_LOOKUP_SIZE) {
for (PsiClassType exceptionType : exceptionTypes) {
PsiClass thrownException = PsiUtil.resolveClassInClassTypeOnly(exceptionType);
if (thrownException != null && !ContainerUtil.or(existedExceptionClasses,
existed-> InheritanceUtil.isInheritorOrSelf(thrownException, existed, true))) {
String qualifiedName = thrownException.getQualifiedName();
if (qualifiedName != null) {
stringExceptions.add(qualifiedName);
DumbService.getInstance(project).withAlternativeResolveEnabled(() -> {
List<PsiClassType> exceptionTypes = getUnhandledExceptionTypes(statements);
if (exceptionTypes.size() <= MAX_LOOKUP_SIZE) {
List<@NotNull PsiClass> existedExceptionClasses =
ContainerUtil.mapNotNull(existedExceptionTypes, exist -> PsiUtil.resolveClassInClassTypeOnly(exist));
for (PsiClassType exceptionType : exceptionTypes) {
PsiClass thrownException = PsiUtil.resolveClassInClassTypeOnly(exceptionType);
if (thrownException != null &&
!ContainerUtil.or(existedExceptionClasses,
existed ->
InheritanceUtil.isInheritorOrSelf(thrownException, existed, true))) {
String qualifiedName = thrownException.getQualifiedName();
if (qualifiedName != null) {
stringExceptions.add(qualifiedName);
}
}
}
}
}
});
if (stringExceptions.isEmpty() || stringExceptions.size() > MAX_LOOKUP_SIZE) {
stringExceptions = getHardcodedExceptions(existedExceptionClasses);
stringExceptions.addAll(getHardcodedExceptions(existedExceptionTypes));
}
}
@@ -139,7 +143,7 @@ final class CatchLookupElement extends LookupItem<PsiCatchSection> {
}
int offset = rParenth.getTextRangeInParent().getEndOffset();
String catchSectionText = catchSection.getText().substring(0, offset);
lookupElements.add(new CatchLookupElement(catchSection, catchSectionText));
lookupElements.add( new CatchLookupElement(catchSection, catchSectionText));
if (lookupElements.size() >= MAX_LOOKUP_SIZE) {
break;
}
@@ -153,10 +157,10 @@ final class CatchLookupElement extends LookupItem<PsiCatchSection> {
}
@NotNull
private static List<String> getHardcodedExceptions(@NotNull Set<PsiClass> existedExceptions) {
private static List<String> getHardcodedExceptions(@NotNull Set<PsiType> existedExceptions) {
ArrayList<String> exceptions = new ArrayList<>();
for (String defaultException : DEFAULT_EXCEPTIONS) {
if (ContainerUtil.exists(existedExceptions, t -> defaultException.equals(t.getQualifiedName()))) {
if (ContainerUtil.exists(existedExceptions, t -> defaultException.equals(t.getCanonicalText()))) {
break;
}
exceptions.add(defaultException);
@@ -0,0 +1,6 @@
class X{
public void test() {
try {
} c<caret>
}
}
@@ -0,0 +1,6 @@
class X{
public void test() {
try {
} catch (Exception e)<caret>
}
}
@@ -0,0 +1,54 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
throw new CheckedException2();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,54 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
throw new CheckedException2();
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,16 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} cat<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,16 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} cat<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,16 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,18 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException1 e) {
} catch(CheckedException2 e) {
} catc<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,18 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException1 e) {
} catch(CheckedException2 e) {
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,17 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException2 e) {
} catc<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,17 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException2 e) {
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,19 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
class CheckedException3 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new CheckedException3();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,19 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
class CheckedException3 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new CheckedException3();
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,11 @@
package com.test3;
import com.test.TestException;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catc<caret>
}
}
@@ -0,0 +1,11 @@
package com.test3;
import com.test.TestException;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catch (TestException e)<caret>
}
}
@@ -0,0 +1,10 @@
package com.test3;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catc<caret>
}
}
@@ -0,0 +1,11 @@
package com.test3;
import com.test.TestException;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catch (TestException e)<caret>
}
}
@@ -0,0 +1,19 @@
class X{
class CheckedException extends Exception {
}
class CheckedException1 extends CheckedException {
}
class CheckedException2 extends CheckedException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException e) {
} catc<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,19 @@
class X{
class CheckedException extends Exception {
}
class CheckedException1 extends CheckedException {
}
class CheckedException2 extends CheckedException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException e) {
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,17 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new RuntimeException();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,17 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new RuntimeException();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,16 @@
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,16 @@
class X{
class CheckedException1 extends RuntimeException {
}
class CheckedException2 extends RuntimeException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,16 @@
class X{
class CheckedException1 extends RuntimeException {
}
class CheckedException2 extends RuntimeException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
@@ -0,0 +1,127 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.NeedsIndex;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@SuppressWarnings("RedundantThrows")
public class NormalCatchSectionCompletionTest extends NormalCompletionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
}
public void testUnhandledCheckedExceptions() {
simpleTestCatchSection(List.of("catch", "catch (CheckedException1 e)", "catch (CheckedException2 e)"));
}
public void testUnhandledCheckedExceptionsWithCatch() {
simpleTestCatchSection(List.of("catch", "catch (CheckedException1 e)"));
}
@NeedsIndex.ForStandardLibrary
public void testUnhandledCheckedExceptionsWithAllCaught() {
simpleTestCatchSection(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"));
}
@NeedsIndex.ForStandardLibrary
public void testUnhandledCheckedExceptionsWithParents() {
simpleTestCatchSection(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"));
}
public void testUnhandledCheckedExceptionsWithExistedImport() {
myFixture.addClass("""
package com.test;
public class TestException extends RuntimeException{}
""");
myFixture.addClass("""
package com.test2;
import com.test.TestException;
public final class Test{
public static void test() throws TestException{}
}
""");
configure();
assertEquals(List.of("catch", "catch (TestException e)"), myFixture.getLookupElementStrings());
LookupElement element = myItems[1];
LookupElementPresentation presentation = renderElement(element);
String text = presentation.getTailText();
assertEquals(" (TestException e)", text);
selectItem(element);
checkResult();
}
public void testUnhandledCheckedExceptionsWithImport() {
myFixture.addClass("""
package com.test;
public class TestException extends RuntimeException{}
""");
myFixture.addClass("""
package com.test2;
import com.test.TestException;
public final class Test{
public static void test() throws TestException{}
}
""");
configure();
assertEquals(List.of("catch", "catch (com.test.TestException e)"), myFixture.getLookupElementStrings());
LookupElement element = myItems[1];
LookupElementPresentation presentation = renderElement(element);
String text = presentation.getTailText();
assertEquals(" (TestException e)", text);
selectItem(element);
checkResult();
}
@NeedsIndex.ForStandardLibrary
public void testManyUnhandledCheckedExceptions() {
simpleTestCatchSection(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"));
}
@NeedsIndex.ForStandardLibrary
public void testUnhandledCheckedExceptionsWithDefault() {
simpleTestCatchSection(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"));
}
public void testUnhandledRuntimeExceptions() {
simpleTestCatchSection(List.of("catch", "catch (CheckedException1 e)", "catch (CheckedException2 e)"));
}
public void testUnhandledCheckedExceptionsWithRuntimeException() {
simpleTestCatchSection(List.of("catch", "catch (CheckedException1 e)", "catch (CheckedException2 e)"));
}
@NeedsIndex.ForStandardLibrary
public void testEmptyTryCatch() {
simpleTestCatchSection(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"));
}
private void simpleTestCatchSection(@NotNull List<String> catches) {
configure();
assertEquals(catches, myFixture.getLookupElementStrings());
selectItem(myItems[1]);
checkResult();
}
}
@@ -2508,581 +2508,6 @@ public class NormalCompletionTest extends NormalCompletionTestCase {
List.of("catch", "finally", "catch (Exception e)", "catch (RuntimeException e)"));
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptions() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (CheckedException1 e)", "catch (CheckedException2 e)"),
myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithCatch() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException2 e) {
} catc<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (CheckedException1 e)"), myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException2 e) {
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithAllCaught() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException1 e) {
} catch(CheckedException2 e) {
} catc<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"), myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException1 e) {
} catch(CheckedException2 e) {
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithParents() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException extends Exception {
}
class CheckedException1 extends CheckedException {
}
class CheckedException2 extends CheckedException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException e) {
} catc<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"), myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException extends Exception {
}
class CheckedException1 extends CheckedException {
}
class CheckedException2 extends CheckedException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch(CheckedException e) {
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithExistedImport() {
myFixture.addClass("""
package com.test;
public class TestException extends RuntimeException{}
""");
myFixture.addClass("""
package com.test2;
import com.test.TestException;
public final class Test{
public static void test() throws TestException{}
}
""");
myFixture.configureByText("Test.java",
"""
package com.test3;
import com.test.TestException;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catc<caret>
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (TestException e)"), myFixture.getLookupElementStrings());
LookupElement element = elements[1];
LookupElementPresentation presentation = renderElement(element);
String text = presentation.getTailText();
assertEquals(" (TestException e)", text);
selectItem(element);
myFixture.checkResult(
"""
package com.test3;
import com.test.TestException;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catch (TestException e)<caret>
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithImport() {
myFixture.addClass("""
package com.test;
public class TestException extends RuntimeException{}
""");
myFixture.addClass("""
package com.test2;
import com.test.TestException;
public final class Test{
public static void test() throws TestException{}
}
""");
myFixture.configureByText("Test.java",
"""
package com.test3;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catc<caret>
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (com.test.TestException e)"), myFixture.getLookupElementStrings());
LookupElement element = elements[1];
LookupElementPresentation presentation = renderElement(element);
String text = presentation.getTailText();
assertEquals(" (TestException e)", text);
selectItem(element);
myFixture.checkResult(
"""
package com.test3;
import com.test.TestException;
import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catch (TestException e)<caret>
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testManyUnhandledCheckedExceptions() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
throw new CheckedException2();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"),
myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
method1();
throw new CheckedException2();
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithDefault() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
class CheckedException3 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new CheckedException3();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"),
myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
class CheckedException3 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new CheckedException3();
} catch (Exception e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledRuntimeExceptions() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends RuntimeException {
}
class CheckedException2 extends RuntimeException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (CheckedException1 e)", "catch (CheckedException2 e)"),
myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends RuntimeException {
}
class CheckedException2 extends RuntimeException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testUnhandledCheckedExceptionsWithRuntimeException() {
myFixture.configureByText("Test.java",
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new RuntimeException();
} c<caret>
}
private void method1() throws CheckedException1{
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (CheckedException1 e)", "catch (CheckedException2 e)"),
myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
class CheckedException1 extends Exception {
}
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new RuntimeException();
} catch (CheckedException1 e)<caret>
}
private void method1() throws CheckedException1{
}
}
""");
}
@NeedsIndex.SmartMode(reason = "CatchLookupElement works only with smart mode")
public void testEmptyTryCatch() {
myFixture.configureByText("Test.java",
"""
class X{
public void test() {
try {
} c<caret>
}
}
""");
LookupElement[] elements = myFixture.completeBasic();
assertEquals(List.of("catch", "catch (Exception e)", "catch (RuntimeException e)"),
myFixture.getLookupElementStrings());
selectItem(elements[1]);
myFixture.checkResult(
"""
class X{
public void test() {
try {
} catch (Exception e)<caret>
}
}
""");
}
@NeedsIndex.ForStandardLibrary
public void testInsertNullable() {
myFixture.configureByText("Test.java", "class X {Stri<caret>}");