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

- catch sections are added automatically

GitOrigin-RevId: 75aed0b2281ffa0e412b1eaecf90caf406ba0182
This commit is contained in:
Mikhail Pyltsin
2024-04-03 20:02:54 +00:00
committed by intellij-monorepo-bot
parent 6e7179de29
commit 55c9701fc8
14 changed files with 138 additions and 121 deletions
@@ -2,13 +2,14 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor;
import com.intellij.codeInsight.generation.surroundWith.SurroundWithUtil;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -71,11 +72,20 @@ final class CatchLookupElement extends LookupItem<PsiCatchSection> {
if (element != null) {
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
PsiElement finalElement = element;
DumbService.getInstance(project)
.runWithAlternativeResolveEnabled(() -> codeStyleManager.shortenClassReferences(finalElement));
element = DumbService.getInstance(project)
.computeWithAlternativeResolveEnabled(() -> codeStyleManager.shortenClassReferences(finalElement));
}
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
new JavaSmartEnterProcessor().process(project, editor, context.getFile());
if (element instanceof PsiCatchSection catchSection) {
catchSection = (PsiCatchSection)CodeStyleManager.getInstance(project).reformat(catchSection);
PsiCodeBlock catchBlock = catchSection.getCatchBlock();
if (catchBlock != null) {
TextRange rangeToSelect = SurroundWithUtil.getRangeToSelect(catchBlock);
context.getEditor().getSelectionModel().setSelection(rangeToSelect.getStartOffset(), rangeToSelect.getEndOffset());
editor.getCaretModel().moveToOffset(rangeToSelect.getEndOffset());
}
}
}
@NotNull
@@ -141,13 +151,7 @@ final class CatchLookupElement extends LookupItem<PsiCatchSection> {
String name =
new VariableNameGenerator(tryStatement, VariableKind.PARAMETER).byName("e", "ex", "exc").generate(false);
PsiCatchSection catchSection = factory.createCatchSection(exceptionType, name, tryStatement);
catchSection = (PsiCatchSection)CodeStyleManager.getInstance(project).reformat(catchSection);
PsiJavaToken rParenth = catchSection.getRParenth();
if (rParenth == null) {
return List.of();
}
int offset = rParenth.getTextRangeInParent().getEndOffset();
String catchSectionText = catchSection.getText().substring(0, offset);
String catchSectionText = catchSection.getText();
lookupElements.add(new CatchLookupElement(catchSection, catchSectionText));
if (lookupElements.size() >= MAX_LOOKUP_SIZE) {
break;
@@ -1,8 +1,8 @@
class X{
public void test() {
try {
} catch (Exception e) {
<caret>
}
try {
} catch (Exception e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
}
@@ -4,50 +4,50 @@ class X{
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>
}
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) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -4,14 +4,14 @@ class X{
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e) {
} catch (CheckedException2 e) {
} catch (Exception e) {
<caret>
}
try {
method1();
throw new CheckedException2();
} catch(CheckedException1 e) {
} catch(CheckedException2 e) {
} catch (Exception e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -4,13 +4,13 @@ class X{
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException2 e) {
} catch (CheckedException1 e) {
<caret>
}
try {
method1();
throw new CheckedException2();
} catch(CheckedException2 e) {
} catch (CheckedException1 e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -6,13 +6,13 @@ class X{
class CheckedException3 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new CheckedException3();
} catch (Exception e) {
<caret>
}
try {
method1();
throw new CheckedException2();
throw new CheckedException3();
} catch (Exception e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -4,10 +4,10 @@ import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catch (TestException e) {
<caret>
}
try {
Test.test();
} catch (TestException e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
}
@@ -4,10 +4,10 @@ import com.test2.Test;
class X{
public void test() {
try {
Test.test();
} catch (TestException e) {
<caret>
}
try {
Test.test();
} catch (TestException e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
}
@@ -6,13 +6,13 @@ class X{
class CheckedException2 extends CheckedException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException e) {
} catch (Exception e) {
<caret>
}
try {
method1();
throw new CheckedException2();
} catch(CheckedException e) {
} catch (Exception e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -4,13 +4,13 @@ class X{
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
throw new RuntimeException();
} catch (CheckedException1 e) {
<caret>
}
try {
method1();
throw new CheckedException2();
throw new RuntimeException();
} catch (CheckedException1 e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -4,12 +4,12 @@ class X{
class CheckedException2 extends Exception {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e) {
<caret>
}
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -4,12 +4,12 @@ class X{
class CheckedException2 extends RuntimeException {
}
public void test() {
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e) {
<caret>
}
try {
method1();
throw new CheckedException2();
} catch (CheckedException1 e) {
<selection>throw new RuntimeException(e);</selection><caret>
}
}
private void method1() throws CheckedException1{
@@ -7,6 +7,7 @@ import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.NeedsIndex;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("RedundantThrows")
@@ -53,7 +54,7 @@ public class NormalCatchSectionCompletionTest extends NormalCompletionTestCase {
configure();
assertEquals(List.of("catch", "catch (TestException e)"), myFixture.getLookupElementStrings());
checkRenderedItems(List.of("catch", "catch (TestException e)"));
LookupElement element = myItems[1];
LookupElementPresentation presentation = renderElement(element);
@@ -81,7 +82,7 @@ public class NormalCatchSectionCompletionTest extends NormalCompletionTestCase {
configure();
assertEquals(List.of("catch", "catch (com.test.TestException e)"), myFixture.getLookupElementStrings());
checkRenderedItems(List.of("catch", "catch (TestException e)"));
LookupElement element = myItems[1];
LookupElementPresentation presentation = renderElement(element);
@@ -118,10 +119,20 @@ public class NormalCatchSectionCompletionTest extends NormalCompletionTestCase {
private void simpleTestCatchSection(@NotNull List<String> catches) {
configure();
assertEquals(catches, myFixture.getLookupElementStrings());
checkRenderedItems(catches);
selectItem(myItems[1]);
checkResult();
}
private void checkRenderedItems(@NotNull List<String> catches) {
List<String> renderedItems = Arrays.stream(myItems).map(t -> {
LookupElementPresentation presentation = new LookupElementPresentation();
t.renderElement(presentation);
return (presentation.getItemText() != null ? presentation.getItemText() : "") +
(presentation.getTailText() != null ? presentation.getTailText() : "");
}).toList();
assertEquals(catches, renderedItems);
}
}
@@ -2505,7 +2505,9 @@ public class NormalCompletionTest extends NormalCompletionTestCase {
myFixture.configureByText("Test.java", "class X{X() {try {}<caret>}}");
myFixture.completeBasic();
assertEquals(myFixture.getLookupElementStrings(),
List.of("catch", "finally", "catch (Exception e)", "catch (RuntimeException e)"));
List.of("catch", "finally",
"catch (Exception e) {\n throw new RuntimeException(e);\n}",
"catch (RuntimeException e) {\n throw new RuntimeException(e);\n}"));
}
@NeedsIndex.ForStandardLibrary