Add 'catch' block after incomplete try (final piece of IDEA-200560)

This commit is contained in:
Tagir Valeev
2018-10-17 13:03:24 +07:00
parent 2d50216e8c
commit 5878fde5e9
12 changed files with 88 additions and 15 deletions

View File

@@ -254,6 +254,5 @@
enabledByDefault="true" level="INFORMATION"
key="inspection.objects.equals.can.be.simplified.display.name" bundle="messages.InspectionsBundle"
implementationClass="com.siyeh.ig.style.ObjectsEqualsCanBeSimplifiedInspection"/>
<errorQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.JavaErrorQuickFixProvider"/>
</extensions>
</idea-plugin>

View File

@@ -1193,5 +1193,6 @@
<category>Serialization</category>
</intentionAction>
<externalAnnotationsArtifactsResolver implementation="com.intellij.jarRepository.ExternalAnnotationsRepositoryResolver"/>
<errorQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.JavaErrorQuickFixProvider"/>
</extensions>
</idea-plugin>

View File

@@ -3,8 +3,10 @@ package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.quickfix.AddExceptionToCatchFix;
import com.intellij.codeInsight.daemon.impl.quickfix.AddFinallyFix;
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.intention.AddFinallyFix;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiTryStatement;
import org.jetbrains.annotations.NotNull;
@@ -12,9 +14,11 @@ import org.jetbrains.annotations.NotNull;
public class JavaErrorQuickFixProvider implements ErrorQuickFixProvider {
@Override
public void registerErrorQuickFix(@NotNull PsiErrorElement errorElement, @NotNull HighlightInfo highlightInfo) {
if (errorElement.getParent() instanceof PsiTryStatement && errorElement.getErrorDescription().equals(
PsiElement parent = errorElement.getParent();
if (parent instanceof PsiTryStatement && errorElement.getErrorDescription().equals(
JavaErrorMessages.message("expected.catch.or.finally"))) {
QuickFixAction.registerQuickFixAction(highlightInfo, new AddFinallyFix((PsiTryStatement)errorElement.getParent()));
QuickFixAction.registerQuickFixAction(highlightInfo, new AddExceptionToCatchFix(false));
QuickFixAction.registerQuickFixAction(highlightInfo, new AddFinallyFix((PsiTryStatement)parent));
}
}
}

View File

@@ -36,6 +36,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
@@ -43,6 +45,11 @@ import java.util.List;
*/
public class AddExceptionToCatchFix extends BaseIntentionAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.AddExceptionToCatchFix");
private final boolean myUncaughtOnly;
public AddExceptionToCatchFix(boolean uncaughtOnly) {
myUncaughtOnly = uncaughtOnly;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
@@ -52,7 +59,7 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
if (element == null) return;
PsiTryStatement tryStatement = (PsiTryStatement)element.getParent();
List<PsiClassType> unhandledExceptions = new ArrayList<>(ExceptionUtil.collectUnhandledExceptions(element, null));
List<PsiClassType> unhandledExceptions = new ArrayList<>(getExceptions(element, null));
if (unhandledExceptions.isEmpty()) return;
ExceptionUtil.sortExceptionsByHierarchy(unhandledExceptions);
@@ -87,6 +94,20 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
}
}
@NotNull
protected Collection<PsiClassType> getExceptions(PsiElement element, PsiElement topElement) {
Collection<PsiClassType> exceptions = ExceptionUtil.collectUnhandledExceptions(element, topElement);
if(!myUncaughtOnly && exceptions.isEmpty()) {
exceptions = ExceptionUtil.getThrownExceptions(element);
if (exceptions.isEmpty()) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject());
PsiClassType exceptionType = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_EXCEPTION, element.getResolveScope());
exceptions = Collections.singleton(exceptionType);
}
}
return exceptions;
}
private static PsiCodeBlock addCatchStatement(PsiTryStatement tryStatement,
PsiClassType exceptionType,
PsiFile file) throws IncorrectOperationException {
@@ -164,7 +185,7 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
}
@Nullable
private static PsiElement findElement(final PsiFile file, final int offset) {
private PsiElement findElement(final PsiFile file, final int offset) {
PsiElement element = file.findElementAt(offset);
if (element instanceof PsiWhiteSpace) element = file.findElementAt(offset - 1);
if (element == null) return null;
@@ -181,15 +202,18 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
final PsiTryStatement statement = (PsiTryStatement) parent;
final PsiCodeBlock tryBlock = statement.getTryBlock();
if (tryBlock != null && tryBlock.getTextRange().contains(offset)) {
if (!ExceptionUtil.collectUnhandledExceptions(tryBlock, statement.getParent()).isEmpty()) {
return tryBlock;
if (tryBlock != null) {
TextRange range = tryBlock.getTextRange();
if (range.contains(offset) || range.getEndOffset() == offset) {
if (!getExceptions(tryBlock, statement.getParent()).isEmpty()) {
return tryBlock;
}
}
}
final PsiResourceList resourceList = statement.getResourceList();
if (resourceList != null && resourceList.getTextRange().contains(offset)) {
if (!ExceptionUtil.collectUnhandledExceptions(resourceList, statement.getParent()).isEmpty()) {
if (!getExceptions(resourceList, statement.getParent()).isEmpty()) {
return resourceList;
}
}

View File

@@ -1,7 +1,8 @@
// 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.intention;
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.generation.surroundWith.JavaWithTryFinallySurrounder;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -10,6 +11,8 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class AddFinallyFix extends BaseIntentionAction {
private final PsiTryStatement myTryStatement;
@@ -41,7 +44,8 @@ public class AddFinallyFix extends BaseIntentionAction {
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
PsiStatement replacement =
JavaPsiFacade.getElementFactory(project).createStatementFromText(myTryStatement.getText() + "finally {}", myTryStatement);
myTryStatement.replace(replacement);
JavaPsiFacade.getElementFactory(project).createStatementFromText(myTryStatement.getText() + "finally {\n\n}", myTryStatement);
PsiTryStatement result = (PsiTryStatement)myTryStatement.replace(replacement);
JavaWithTryFinallySurrounder.moveCaretToFinallyBlock(project, editor, Objects.requireNonNull(result.getFinallyBlock()));
}
}

View File

@@ -63,6 +63,11 @@ public class JavaWithTryFinallySurrounder extends JavaStatementsSurrounder{
if (finallyBlock == null) {
return null;
}
moveCaretToFinallyBlock(project, editor, finallyBlock);
return new TextRange(editor.getCaretModel().getOffset(), editor.getCaretModel().getOffset());
}
public static void moveCaretToFinallyBlock(Project project, Editor editor, PsiCodeBlock finallyBlock) {
Document document = editor.getDocument();
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
TextRange finallyBlockRange = finallyBlock.getTextRange();
@@ -71,6 +76,5 @@ public class JavaWithTryFinallySurrounder extends JavaStatementsSurrounder{
editor.getSelectionModel().removeSelection();
CodeStyleManager.getInstance(project).adjustLineIndent(document, newLineOffset);
PsiDocumentManager.getInstance(project).commitDocument(document);
return new TextRange(editor.getCaretModel().getOffset(), editor.getCaretModel().getOffset());
}
}

View File

@@ -205,7 +205,7 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
@NotNull
@Override
public IntentionAction createAddExceptionToCatchFix() {
return new AddExceptionToCatchFix();
return new AddExceptionToCatchFix(true);
}
@NotNull

View File

@@ -0,0 +1,10 @@
// "Add 'catch' clause(s)" "true"
class Foo {
void test(String s) {
try {
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,10 @@
// "Add 'catch' clause(s)" "true"
class Foo {
void test(String s) {
try {
System.out.println(Integer.parseInt(s));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,8 @@
// "Add 'catch' clause(s)" "true"
class Foo {
void test(String s) {
try {
System.out.println(s);
}<caret>
}
}

View File

@@ -0,0 +1,8 @@
// "Add 'catch' clause(s)" "true"
class Foo {
void test(String s) {
try {
System.out.println(Integer.parseInt(s));
}<caret>
}
}

View File

@@ -3,6 +3,7 @@ class Test {
void foo() {
try {
} finally {
}
}
}