[mod-command] AddExceptionToCatchFix: ModCommandAction; injection test

GitOrigin-RevId: 9a3ab90be0420b79f913c96b0d0101e538e6fca6
This commit is contained in:
Tagir Valeev
2023-05-10 11:33:28 +02:00
committed by intellij-monorepo-bot
parent ff7bded456
commit 92839cf245
7 changed files with 68 additions and 35 deletions

View File

@@ -30,7 +30,7 @@ public class JavaErrorQuickFixProvider implements ErrorQuickFixProvider {
HighlightFixUtil.registerFixesForExpressionStatement((PsiStatement)parent, registrar);
}
if (parent instanceof PsiTryStatement && description.equals(JavaPsiBundle.message("expected.catch.or.finally"))) {
registrar.add(new AddExceptionToCatchFix(false));
registrar.add(new AddExceptionToCatchFix(false).asIntention());
registrar.add(new AddFinallyFix((PsiTryStatement)parent).asIntention());
}
if (parent instanceof PsiSwitchLabeledRuleStatement && description.equals(JavaPsiBundle.message("expected.switch.rule"))) {

View File

@@ -1,17 +1,17 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.generation.surroundWith.SurroundWithUtil;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.codeInspection.EditorUpdater;
import com.intellij.codeInspection.ModCommands;
import com.intellij.modcommand.ModCommand;
import com.intellij.modcommand.ModCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
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;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTreeUtil;
@@ -27,7 +27,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AddExceptionToCatchFix extends BaseIntentionAction {
public class AddExceptionToCatchFix implements ModCommandAction {
private static final Logger LOG = Logger.getInstance(AddExceptionToCatchFix.class);
private final boolean myUncaughtOnly;
@@ -36,22 +36,22 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
int offset = editor.getCaretModel().getOffset();
public @NotNull ModCommand perform(@NotNull ActionContext context) {
int offset = context.offset();
PsiElement element = findElement(file, offset);
if (element == null) return;
PsiElement element = findElement(context.file(), offset);
if (element == null) return ModCommands.nop();
PsiTryStatement tryStatement = (PsiTryStatement)element.getParent();
List<PsiClassType> unhandledExceptions = new ArrayList<>(getExceptions(element, null));
if (unhandledExceptions.isEmpty()) return;
if (unhandledExceptions.isEmpty()) return ModCommands.nop();
ExceptionUtil.sortExceptionsByHierarchy(unhandledExceptions);
if (file.isPhysical()) {
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
}
return ModCommands.psiUpdate(tryStatement, (ts, updater) -> invoke(ts, unhandledExceptions, updater));
}
private static void invoke(@NotNull PsiTryStatement tryStatement, @NotNull List<PsiClassType> unhandledExceptions, @NotNull EditorUpdater updater) {
PsiFile file = tryStatement.getContainingFile();
PsiCodeBlock catchBlockToSelect = null;
try {
@@ -72,11 +72,9 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
LOG.error(e);
}
if (catchBlockToSelect != null) {
catchBlockToSelect = (PsiCodeBlock)CodeStyleManager.getInstance(file.getProject()).reformat(catchBlockToSelect);
TextRange range = SurroundWithUtil.getRangeToSelect(catchBlockToSelect);
editor.getCaretModel().moveToOffset(range.getStartOffset());
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
updater.select(range);
}
}
@@ -157,16 +155,14 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!(file instanceof PsiJavaFile)) return false;
public @Nullable Presentation getPresentation(@NotNull ActionContext context) {
PsiFile file = context.file();
if (!(file instanceof PsiJavaFile)) return null;
int offset = editor.getCaretModel().getOffset();
PsiElement element = findElement(file, offset);
if (element == null) return false;
setText(QuickFixBundle.message("add.catch.clause.text"));
return true;
PsiElement element = findElement(file, context.offset());
if (element == null) return null;
return Presentation.of(QuickFixBundle.message("add.catch.clause.text"));
}
@Nullable

View File

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

View File

@@ -0,0 +1,16 @@
// "Add 'catch' clause(s)" "true-preview"
import org.intellij.lang.annotations.Language;
class X {
@Language("JAVA") String java = """
class Cls {
{
try {
} catch (Exception e) {
<selection><caret>throw new RuntimeException(e);</selection>
}
}
}
""";
}

View File

@@ -0,0 +1,14 @@
// "Add 'catch' clause(s)" "true-preview"
import org.intellij.lang.annotations.Language;
class X {
@Language("JAVA") String java = """
class Cls {
{
try {
}<caret>
}
}
""";
}

View File

@@ -1,11 +1,17 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase5;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach;
public class AddExceptionToCatchTest extends LightQuickFixParameterizedTestCase5 {
@BeforeEach
public void setUp() {
getFixture().setCaresAboutInjection(false);
}
@Override
protected @NotNull String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/addCatchBlock";

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.quickFix
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.psi.util.PsiUtil
@@ -43,7 +44,7 @@ abstract class LightQuickFixParameterizedTestCase5(projectDescriptor: LightProje
fun parameterized(fileName: String) {
val filePath = "/" + LightQuickFixTestCase.BEFORE_PREFIX + fileName
val file = fixture.configureByFile(filePath)
val action = ActionHint.parse(file, file.text).findAndCheck(fixture.availableIntentions) {
val action = runReadAction { ActionHint.parse(file, file.text) }.findAndCheck(fixture.availableIntentions) {
"""
Test: ${getRelativePath() + filePath}
Language level: ${PsiUtil.getLanguageLevel(fixture.project)}