From 9fd6ada97046e4c6ea905a5304587f823172ca5b Mon Sep 17 00:00:00 2001 From: Marcin Mikosik Date: Thu, 21 Aug 2025 09:10:24 +0000 Subject: [PATCH] [java] IDEA-283208 Add quickfix: Lift 'throw' out of 'switch' expression Adds a quick-fix: "Lift 'throw' out of 'switch' expression" that that is provided for error "'switch' expression does not have any result expressions". Some rare cases are not handled (fix is not provided for mentioned error). For example when switch is used inside: - initialization/condition/update part of for loop - initializer of class field - condition of do-while loop - lock expression in synchronized statement - any part of assert statement - resource initializer of 'try' statement #IDEA-283208 Fixed Merge-request: IJ-MR-172146 Merged-by: Marcin Mikosik GitOrigin-RevId: a2710c49e16b7f495974fb167bcae01b3d850f7b --- .../intention/QuickFixFactory.java | 1 + .../messages/QuickFixBundle.properties | 3 +- .../analysis/DefaultJavaErrorFixProvider.java | 4 +- .../LiftThrowOutOfSwitchExpressionFix.java | 257 ++++++++++++++++++ .../impl/config/QuickFixFactoryImpl.java | 6 + ...fterDoesntLiftThrowFromAnonymousClass.java | 16 ++ ...sntLiftThrowFromInnerSwitchExpression.java | 19 ++ .../afterDoesntLiftThrowFromLambda.java | 15 + .../afterDoesntLiftThrowFromLocalClass.java | 16 ++ .../afterLiftingThrowsKeepsComments.java | 20 ++ .../afterLiftsThrowFromCodeBlock.java | 13 + .../afterLiftsThrowFromForLoop.java | 14 + .../afterLiftsThrowFromIfClauses.java | 15 + ...erLiftsThrowFromNestedSwitchStatement.java | 16 ++ ...witchStatementLabeledRuleWithoutBlock.java | 17 ++ ...tsThrowFromSwitchLabelBlockStatements.java | 20 ++ ...tsThrowFromSwitchLabelThrowStatements.java | 14 + .../afterLiftsThrowFromSwitchStatement.java | 14 + .../afterLiftsThrowFromWhileLoop.java | 14 + ...itchInsideBinaryExpressionAsFirstElem.java | 10 + ...tchInsideBinaryExpressionAsSecondElem.java | 11 + ...onInsideSwitchLabeledRuleWithoutBlock.java | 17 ++ ...xpressionInsideThenClauseWithoutBlock.java | 17 ++ .../afterSwitchInsideCall.java | 13 + .../afterSwitchInsideCallInsideCall.java | 17 ++ .../afterSwitchInsideCallInsideThrow.java | 15 + .../afterSwitchInsideForLoopBody.java | 11 + .../afterSwitchInsideForeachInitializer.java | 10 + .../afterSwitchInsideIfConfition.java | 11 + ...tchInsideMultipleVariablesDeclaration.java | 12 + .../afterSwitchInsidePolyadicExpression.java | 12 + ...icExpressionInsideVariableDeclaration.java | 12 + .../afterSwitchInsideReturn.java | 9 + ...chInsideSwitchLabeledRuleWithoutBlock.java | 13 + .../afterSwitchInsideThrow.java | 9 + .../afterSwitchInsideVariableAssignment.java | 10 + .../afterSwitchInsideVariableDeclaration.java | 9 + .../afterSwitchInsideWhileLoopCondition.java | 10 + .../afterSwitchInsideYield.java | 14 + ...foreDoesntLiftThrowFromAnonymousClass.java | 16 ++ ...sntLiftThrowFromInnerSwitchExpression.java | 19 ++ .../beforeDoesntLiftThrowFromLambda.java | 15 + .../beforeDoesntLiftThrowFromLocalClass.java | 16 ++ ...sntSupportSwitchInsideAssertCondition.java | 7 + ...oesntSupportSwitchInsideAssertMessage.java | 7 + ...reDoesntSupportSwitchInsideClassField.java | 5 + ...portSwitchInsideConditionalExpression.java | 7 + ...pportSwitchInsideDoWhileLoopCondition.java | 10 + ...DoesntSupportSwitchInsideForCondition.java | 8 + ...tSupportSwitchInsideForInitialization.java | 8 + ...oreDoesntSupportSwitchInsideForUpdate.java | 8 + ...sntSupportSwitchInsideLocalClassField.java | 10 + ...itchInsideNestedConditionalExpression.java | 10 + ...ortSwitchInsideSynchronizedExpression.java | 8 + ...SwitchInsideTryResourceInitialization.java | 8 + .../beforeLiftingThrowsKeepsComments.java | 19 ++ .../beforeLiftsThrowFromCodeBlock.java | 13 + .../beforeLiftsThrowFromForLoop.java | 14 + .../beforeLiftsThrowFromIfClauses.java | 15 + ...reLiftsThrowFromNestedSwitchStatement.java | 16 ++ ...witchStatementLabeledRuleWithoutBlock.java | 13 + ...tsThrowFromSwitchLabelBlockStatements.java | 20 ++ ...tsThrowFromSwitchLabelThrowStatements.java | 14 + .../beforeLiftsThrowFromSwitchStatement.java | 14 + .../beforeLiftsThrowFromWhileLoop.java | 14 + ...itchInsideBinaryExpressionAsFirstElem.java | 10 + ...tchInsideBinaryExpressionAsSecondElem.java | 10 + ...onInsideSwitchLabeledRuleWithoutBlock.java | 14 + ...xpressionInsideThenClauseWithoutBlock.java | 16 ++ .../beforeSwitchInsideCall.java | 14 + .../beforeSwitchInsideCallInsideCall.java | 21 ++ .../beforeSwitchInsideCallInsideThrow.java | 16 ++ .../beforeSwitchInsideForLoopBody.java | 9 + .../beforeSwitchInsideForeachInitializer.java | 10 + .../beforeSwitchInsideIfConfition.java | 13 + ...tchInsideMultipleVariablesDeclaration.java | 9 + .../beforeSwitchInsidePolyadicExpression.java | 11 + ...icExpressionInsideVariableDeclaration.java | 11 + .../beforeSwitchInsideReturn.java | 9 + ...chInsideSwitchLabeledRuleWithoutBlock.java | 11 + .../beforeSwitchInsideThrow.java | 9 + .../beforeSwitchInsideVariableAssignment.java | 10 + ...beforeSwitchInsideVariableDeclaration.java | 9 + .../beforeSwitchInsideWhileLoopCondition.java | 10 + .../beforeSwitchInsideYield.java | 14 + ...LiftThrowOutOfSwitchExpressionFixTest.java | 11 + 86 files changed, 1295 insertions(+), 2 deletions(-) create mode 100644 java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFix.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromAnonymousClass.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromInnerSwitchExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLambda.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLocalClass.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftingThrowsKeepsComments.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromCodeBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromForLoop.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromIfClauses.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatement.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelBlockStatements.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelThrowStatements.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchStatement.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromWhileLoop.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsFirstElem.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsSecondElem.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCall.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideCall.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideThrow.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForLoopBody.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForeachInitializer.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideIfConfition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideMultipleVariablesDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpressionInsideVariableDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideReturn.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideSwitchLabeledRuleWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideThrow.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableAssignment.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideWhileLoopCondition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideYield.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromAnonymousClass.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromInnerSwitchExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLambda.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLocalClass.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertCondition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertMessage.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideClassField.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideConditionalExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideDoWhileLoopCondition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForCondition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForInitialization.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForUpdate.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideLocalClassField.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideNestedConditionalExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideSynchronizedExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideTryResourceInitialization.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftingThrowsKeepsComments.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromCodeBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromForLoop.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromIfClauses.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatement.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelBlockStatements.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelThrowStatements.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchStatement.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromWhileLoop.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsFirstElem.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsSecondElem.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCall.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideCall.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideThrow.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForLoopBody.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForeachInitializer.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideIfConfition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideMultipleVariablesDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpression.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpressionInsideVariableDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideReturn.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideSwitchLabeledRuleWithoutBlock.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideThrow.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableAssignment.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideWhileLoopCondition.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideYield.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFixTest.java diff --git a/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java index e3614060524f..3a4bd345108e 100644 --- a/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java +++ b/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java @@ -527,4 +527,5 @@ public abstract class QuickFixFactory { public abstract @Nullable ModCommandAction createRecordThisDelegateFix(PsiMethod psi); + public abstract @Nullable CommonIntentionAction createLiftThrowOutOfSwitchExpression(@NotNull PsiSwitchExpression psiSwitchExpression); } \ No newline at end of file diff --git a/java/java-analysis-impl/resources/messages/QuickFixBundle.properties b/java/java-analysis-impl/resources/messages/QuickFixBundle.properties index f7173748afcf..949081f8e8e7 100644 --- a/java/java-analysis-impl/resources/messages/QuickFixBundle.properties +++ b/java/java-analysis-impl/resources/messages/QuickFixBundle.properties @@ -458,4 +458,5 @@ add.missing.nested.patterns.fix.text=Add missing nested pattern{0, choice, 1#|2# add.missing.str.processor=Add 'STR.' Processor -record.delegate.to.canonical.constructor.fix.name=Delegate to canonical constructor \ No newline at end of file +record.delegate.to.canonical.constructor.fix.name=Delegate to canonical constructor +lift.throw.out.of.switch.expression.fix.name=Lift 'throw' out of 'switch' expression \ No newline at end of file diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java index ee56179564b5..8a09197f5279 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java @@ -14,7 +14,6 @@ import com.intellij.codeInspection.dataFlow.fix.RedundantInstanceofFix; import com.intellij.core.JavaPsiBundle; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.java.analysis.JavaAnalysisBundle; -import com.intellij.java.codeserver.core.JavaPsiMethodUtil; import com.intellij.java.codeserver.core.JavaPsiModifierUtil; import com.intellij.java.codeserver.core.JavaPsiSwitchUtil; import com.intellij.java.codeserver.core.JpmsModuleAccessInfo; @@ -250,6 +249,9 @@ public final class DefaultJavaErrorFixProvider extends AbstractJavaErrorFixProvi } return null; }); + fix(SWITCH_EXPRESSION_NO_RESULT, error -> { + return myFactory.createLiftThrowOutOfSwitchExpression(error.psi()); + }); fix(SYNTAX_ERROR, error -> error.psi().getParent() instanceof PsiSwitchLabeledRuleStatement rule && error.psi().getErrorDescription().equals(JavaPsiBundle.message("expected.switch.rule")) ? myFactory.createWrapSwitchRuleStatementsIntoBlockFix(rule) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFix.java new file mode 100644 index 000000000000..27120d120c26 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFix.java @@ -0,0 +1,257 @@ +// Copyright 2000-2025 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.QuickFixBundle; +import com.intellij.modcommand.ActionContext; +import com.intellij.modcommand.ModPsiUpdater; +import com.intellij.modcommand.PsiUpdateModCommandAction; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.SmartHashSet; +import com.siyeh.ig.psiutils.CommentTracker; +import com.siyeh.ig.psiutils.SideEffectChecker; +import com.siyeh.ig.psiutils.StatementExtractor; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNullByDefault; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; + +import static com.intellij.codeInsight.BlockUtils.expandSingleStatementToBlockStatement; + +/** + * This class provides a quick fix to lift a throw expression out of a switch expression + * when all execution branches of the switch expression end with a throw statement. + */ +@NotNullByDefault +public class LiftThrowOutOfSwitchExpressionFix extends PsiUpdateModCommandAction { + public static @Nullable LiftThrowOutOfSwitchExpressionFix create(PsiSwitchExpression switchExpression) { + return isAvailable(switchExpression) ? new LiftThrowOutOfSwitchExpressionFix(switchExpression) : null; + } + + private static boolean isAvailable(PsiSwitchExpression switchExpression) { + PsiStatement enclosingStatement = enclosingStatementOf(switchExpression); + if (enclosingStatement == null) return false; + // Fix is not available when switch is inside for's initializer OR condition OR update. + if (enclosingStatement.getParent() instanceof PsiForStatement) return false; + if (enclosingStatement instanceof PsiDeclarationStatement declarationStatement) { + PsiElement[] elements = declarationStatement.getDeclaredElements(); + return 0 < elements.length && elements[0] instanceof PsiLocalVariable; + } + if (isInsideConditionalExpression(switchExpression)) return false; + return (topmostExpressionOf(enclosingStatement) != null); + } + + private static boolean isInsideConditionalExpression(PsiElement element) { + return PsiTreeUtil.getParentOfType(element, PsiStatement.class, PsiConditionalExpression.class) instanceof PsiConditionalExpression; + } + + private LiftThrowOutOfSwitchExpressionFix(PsiSwitchExpression expression) { + super(expression); + } + + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) String getFamilyName() { + return QuickFixBundle.message("lift.throw.out.of.switch.expression.fix.name"); + } + + @Override + protected void invoke(ActionContext context, PsiSwitchExpression switchExpression, ModPsiUpdater updater) { + PsiCodeBlock body = switchExpression.getBody(); + if (body == null) return; + PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.project()); + replaceThrowStatementsInsideSwitchBodyScope(body, factory); + + PsiStatement enclosingStatement = enclosingStatementOf(switchExpression); + if (enclosingStatement == null) return; + + if (enclosingStatement instanceof PsiDeclarationStatement declarationStatement) { + replaceDeclarationStatementWithThrowStatement(declarationStatement, switchExpression, factory, updater); + } + else { + PsiExpression mainExpression = topmostExpressionOf(enclosingStatement); + if (mainExpression != null) { + replaceStatementWithThrowStatement(enclosingStatement, mainExpression, switchExpression, factory, updater); + } + } + } + + private static @Nullable PsiStatement enclosingStatementOf(PsiSwitchExpression switchExpression) { + return PsiTreeUtil.getParentOfType(switchExpression, PsiStatement.class); + } + + private static void replaceThrowStatementsInsideSwitchBodyScope(PsiCodeBlock body, PsiElementFactory factory) { + for (PsiStatement statement : body.getStatements()) { + if (statement instanceof PsiSwitchLabeledRuleStatement ruleStatement) { + PsiStatement ruleBody = ruleStatement.getBody(); + if (ruleBody instanceof PsiThrowStatement throwStatement) { + replaceThrowStatementWithExceptionExpression(throwStatement, factory); + } + else if (ruleBody != null) { + replaceThrowStatementsWithYieldStatements(ruleBody, factory); + } + } + else { + replaceThrowStatementsWithYieldStatements(statement, factory); + } + } + } + + private static void replaceThrowStatementWithExceptionExpression(PsiThrowStatement throwStatement, PsiElementFactory factory) { + PsiExpression exception = throwStatement.getException(); + CommentTracker commentTracker = new CommentTracker(); + String exceptionText = exception != null ? commentTracker.text(exception) : ""; + commentTracker.replaceAndRestoreComments(throwStatement, factory.createStatementFromText(exceptionText + ";", throwStatement)); + } + + private static void replaceThrowStatementsWithYieldStatements(PsiElement element, PsiElementFactory factory) { + for (PsiThrowStatement throwStatement : collectThrowStatements(element)) { + replaceThrowStatementWithYieldStatement(throwStatement, factory); + } + } + + /** + * Returns all throw statements that are contained in the scope of the psiElement + * excluding those from scopes of nested classes, lambda expressions, switch expressions. + */ + private static Set collectThrowStatements(PsiElement psiElement) { + SmartHashSet throwStatements = new SmartHashSet<>(); + if (psiElement instanceof PsiThrowStatement throwStatement) { + throwStatements.add(throwStatement); + return throwStatements; + } + var visitor = new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitThrowStatement(PsiThrowStatement throwStatement) { + throwStatements.add(throwStatement); + } + + @Override + public void visitClass(PsiClass aClass) { } + + @Override + public void visitSwitchExpression(PsiSwitchExpression expression) { } + + @Override + public void visitLambdaExpression(PsiLambdaExpression expression) { } + }; + visitor.visitElement(psiElement); + return throwStatements; + } + + private static void replaceThrowStatementWithYieldStatement(PsiThrowStatement throwStatement, PsiElementFactory factory) { + PsiExpression exception = throwStatement.getException(); + var commentTracker = new CommentTracker(); + var exceptionText = exception != null ? commentTracker.text(exception) : ""; + var yieldText = "yield " + exceptionText + ";"; + var yieldStatement = factory.createStatementFromText(yieldText, throwStatement); + var newYield = commentTracker.replaceAndRestoreComments(throwStatement, yieldStatement); + if (newYield.getParent() instanceof PsiSwitchLabeledRuleStatement) { + expandSingleStatementToBlockStatement((PsiStatement)newYield); + } + } + + /** + * Replaces the enclosingStatement with (in order) + * 1) all side effects of the enclosingStatement that precede switchExpression within the enclosingStatement + * 2) a throw statement with the switchExpression + */ + private static void replaceDeclarationStatementWithThrowStatement(PsiDeclarationStatement enclosingStatement, + PsiSwitchExpression switchExpression, + PsiElementFactory factory, + ModPsiUpdater updater) { + var enclosingVariable = PsiTreeUtil.getParentOfType(switchExpression, PsiLocalVariable.class); + for (PsiElement element : enclosingStatement.getDeclaredElements()) { + if (element == enclosingVariable) { + PsiExpression initializer = enclosingVariable.getInitializer(); + if (initializer != null) { + replaceStatementWithThrowStatement(enclosingStatement, initializer, switchExpression, factory, updater); + } + break; + } + else { + if (element instanceof PsiLocalVariable variable) { + var variableDeclaration = + factory.createVariableDeclarationStatement(variable.getName(), variable.getType(), variable.getInitializer()); + enclosingStatement.getParent().addBefore(variableDeclaration, enclosingStatement); + } + } + } + } + + private static @Nullable PsiExpression topmostExpressionOf(PsiStatement statement) { + if (statement instanceof PsiReturnStatement returnStatement) { + return returnStatement.getReturnValue(); + } + else if (statement instanceof PsiExpressionStatement expressionStatement) { + return expressionStatement.getExpression(); + } + else if (statement instanceof PsiThrowStatement throwStatement) { + return throwStatement.getException(); + } + else if (statement instanceof PsiIfStatement ifStatement) { + return ifStatement.getCondition(); + } + else if (statement instanceof PsiWhileStatement whileStatement) { + return whileStatement.getCondition(); + } + else if (statement instanceof PsiForeachStatementBase foreachStatementBase) { + return foreachStatementBase.getIteratedValue(); + } + else if (statement instanceof PsiYieldStatement yieldStatement) { + return yieldStatement.getExpression(); + } + return null; + } + + /** + * Replaces the enclosingStatement with (in order): + * 1) all side effects of the enclosingStatement that precede switchExpression within the enclosingStatement + * 2) a throw statement with the switchExpression + */ + private static void replaceStatementWithThrowStatement(PsiStatement enclosingStatement, + PsiExpression enclosingExpression, + PsiSwitchExpression switchExpression, + PsiElementFactory factory, ModPsiUpdater updater) { + var precedingExpressions = findAllPrecedingExpressionsInsideAncestor(switchExpression, enclosingExpression); + var expressions = SideEffectChecker.extractSideEffectExpressions(enclosingExpression, e -> !precedingExpressions.contains(e)); + PsiStatement[] statements = StatementExtractor.generateStatements(expressions, enclosingExpression); + + var commentTracker = new CommentTracker(); + var throwText = "throw " + commentTracker.text(switchExpression) + ";"; + var throwStatement = + commentTracker.replaceAndRestoreComments(enclosingStatement, factory.createStatementFromText(throwText, switchExpression)); + if (!(throwStatement.getParent() instanceof PsiCodeBlock)) { + throwStatement = expandSingleStatementToBlockStatement((PsiStatement)throwStatement); + } + for (PsiStatement statement : statements) { + throwStatement.getParent().addBefore(statement, throwStatement); + } + PsiExpression exception = ((PsiThrowStatement)throwStatement).getException(); + if (exception != null) { + updater.moveCaretTo(exception.getTextOffset()); + } + } + + /** + * Returns all expressions of the ancestor that are executed in runtime before the descendant. + */ + private static Set findAllPrecedingExpressionsInsideAncestor(PsiElement descendant, + PsiElement ancestor) { + Set set = new SmartHashSet<>(); + PsiElement current = descendant; + while (true) { + var preceding = current.getPrevSibling(); + while (preceding == null) { + var parent = current.getParent(); + if (parent == null || parent == ancestor) return set; + current = parent; + preceding = parent.getPrevSibling(); + } + if (preceding instanceof PsiExpression psiExpression) { + set.add(psiExpression); + } + current = preceding; + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java index 970458157469..922acfc8ea6c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java @@ -1158,4 +1158,10 @@ public final class QuickFixFactoryImpl extends QuickFixFactory { ReplaceOnDemandImportIntention.replaceOnDemand(element); } } + + @Override + public @Nullable IntentionAction createLiftThrowOutOfSwitchExpression(@NotNull PsiSwitchExpression psiSwitchExpression) { + LiftThrowOutOfSwitchExpressionFix fix = LiftThrowOutOfSwitchExpressionFix.create(psiSwitchExpression); + return fix != null ? fix.asIntention() : null; + } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromAnonymousClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromAnonymousClass.java new file mode 100644 index 000000000000..f52604412a43 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromAnonymousClass.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + new Runnable() { + public void run() { + throw new RuntimeException("runnable"); + } + }.run(); + yield new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromInnerSwitchExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromInnerSwitchExpression.java new file mode 100644 index 000000000000..15fe75fb79de --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromInnerSwitchExpression.java @@ -0,0 +1,19 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + int x = switch (5) { + case 1: + throw new RuntimeException("one"); + case 2: + yield 3; + default: + throw new RuntimeException("default"); + }; + yield new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLambda.java new file mode 100644 index 000000000000..29f26cc88b09 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLambda.java @@ -0,0 +1,15 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + Runnable runnable = () -> { + throw new RuntimeException("runnable"); + }; + runnable.run(); + yield new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLocalClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLocalClass.java new file mode 100644 index 000000000000..044e27743a03 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterDoesntLiftThrowFromLocalClass.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + class LocalClass { + public void fooBar() { + throw new RuntimeException("local classs"); + } + } + yield new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftingThrowsKeepsComments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftingThrowsKeepsComments.java new file mode 100644 index 000000000000..69a8d05dc6f2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftingThrowsKeepsComments.java @@ -0,0 +1,20 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + // BEFORE STATEMENT + /* INSIDE 0*/ + throw switch /*INSIDE 1*/ (7) { + // BEFORE FIRST + case 1 -> new /*INSIDE 2*/ RuntimeException("one"); // TRAILING + // BETWEEN + default -> { + // BEFORE + yield new /*INSIDE 3*/ RuntimeException("default"); // TRAILING + // AFTER + } + // AFTER LAST + }; + // AFTER STATEMENT + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromCodeBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromCodeBlock.java new file mode 100644 index 000000000000..ef51c4ec69c1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromCodeBlock.java @@ -0,0 +1,13 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + { + yield new RuntimeException("then"); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromForLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromForLoop.java new file mode 100644 index 000000000000..998346d86f2c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromForLoop.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + for (int i = 0; i < new java.util.Random().nextInt(); i++) { + yield new RuntimeException("for"); + } + yield new RuntimeException("default"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromIfClauses.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromIfClauses.java new file mode 100644 index 000000000000..9ae1ae3e8d7d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromIfClauses.java @@ -0,0 +1,15 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + if (true) { + yield new RuntimeException("then"); + } else { + yield new RuntimeException("else"); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatement.java new file mode 100644 index 000000000000..2d4c4debde60 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatement.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + switch (5) { + case 1: + yield new RuntimeException("one"); + default: + yield new RuntimeException("default"); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java new file mode 100644 index 000000000000..927fea0dbf74 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java @@ -0,0 +1,17 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + throw switch (param) { + default: + switch (param) { + case 1 -> { + yield new RuntimeException(); + } + default -> { + yield new RuntimeException(); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelBlockStatements.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelBlockStatements.java new file mode 100644 index 000000000000..8fdd4b72cf09 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelBlockStatements.java @@ -0,0 +1,20 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + enum Two { + ONE, TWO; + } + int bar(Two param) { + throw switch (param) { + case ONE -> { + yield new RuntimeException("1"); + } + case TWO -> { + yield new RuntimeException("2"); + } + default -> { + yield new RuntimeException("default"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelThrowStatements.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelThrowStatements.java new file mode 100644 index 000000000000..a83ed106d9ea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchLabelThrowStatements.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + enum Three { + ONE, TWO; + } + int bar(Three param) { + throw switch (param) { + case ONE -> new RuntimeException("1"); + case TWO -> new RuntimeException("2"); + default -> new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchStatement.java new file mode 100644 index 000000000000..8c167c6424d5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromSwitchStatement.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param, boolean b) { + throw switch (param) { + case 1: + if (b) { + yield new RuntimeException("one"); + } + default: + yield new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromWhileLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromWhileLoop.java new file mode 100644 index 000000000000..b9d693245937 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterLiftsThrowFromWhileLoop.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + throw switch (7) { + default -> { + while (new java.util.Random().nextBoolean()) { + yield new RuntimeException("while"); + } + yield new RuntimeException("default"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsFirstElem.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsFirstElem.java new file mode 100644 index 000000000000..a5779cc7f1f5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsFirstElem.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + int a() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsSecondElem.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsSecondElem.java new file mode 100644 index 000000000000..83e38094d282 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionAsSecondElem.java @@ -0,0 +1,11 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + a(); + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + int a() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java new file mode 100644 index 000000000000..e5b4f1969cad --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java @@ -0,0 +1,17 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +public class Foo { + public int bar(int param) { + switch (param) { + default -> { + call(); + throw switch (param) { + default -> new ArithmeticException(); + }; + } + } + } + public int call() { + return 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java new file mode 100644 index 000000000000..b5200b24e023 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java @@ -0,0 +1,17 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +public class Foo { + public int bar(int param) { + if (param==2) { + call(1); + throw switch (param) { + default -> new ArithmeticException(); + }; + } else { + return 1; + } + } + public int call(Object... param) { + return 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCall.java new file mode 100644 index 000000000000..20dbabcd77ce --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCall.java @@ -0,0 +1,13 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + methodA(1); + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + void parentMethod(int x, int y, int z) {} + void methodA(int x) {} + void methodB(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideCall.java new file mode 100644 index 000000000000..7076bc7e151a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideCall.java @@ -0,0 +1,17 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + a(1); + b(2); + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + void parentMethod(int x, int y, int z) {} + int nestedMethod(int x, int y, int z) {} + void a(int x) {} + void b(int x) {} + void c(int x) {} + void d(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideThrow.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideThrow.java new file mode 100644 index 000000000000..41b28ee06db8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideCallInsideThrow.java @@ -0,0 +1,15 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + a(1); + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + Exception newException(int x, int y, int z) { + return new RuntimeException(); + } + void a(int x) {} + void b(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForLoopBody.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForLoopBody.java new file mode 100644 index 000000000000..7c377b09befc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForLoopBody.java @@ -0,0 +1,11 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + for (int i = 0; i < 10; i++) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForeachInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForeachInitializer.java new file mode 100644 index 000000000000..c19601fb5f7b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideForeachInitializer.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + void methodA(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideIfConfition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideIfConfition.java new file mode 100644 index 000000000000..76fd91111b86 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideIfConfition.java @@ -0,0 +1,11 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + void methodA(int x) {} + void methodB(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideMultipleVariablesDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideMultipleVariablesDeclaration.java new file mode 100644 index 000000000000..20496bc43a45 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideMultipleVariablesDeclaration.java @@ -0,0 +1,12 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + int a = 3; + int b; + int c = 4; + throw switch (param) { + default -> new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpression.java new file mode 100644 index 000000000000..b4b7b84398e5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpression.java @@ -0,0 +1,12 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + a(); + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + int a() {return 0;} + int b() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpressionInsideVariableDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpressionInsideVariableDeclaration.java new file mode 100644 index 000000000000..9028325b414d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsidePolyadicExpressionInsideVariableDeclaration.java @@ -0,0 +1,12 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(Three param) { + a(); + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + int a() {return 0;} + int b() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideReturn.java new file mode 100644 index 000000000000..0896ca83fd07 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideReturn.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideSwitchLabeledRuleWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideSwitchLabeledRuleWithoutBlock.java new file mode 100644 index 000000000000..9f3d3bab5e23 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideSwitchLabeledRuleWithoutBlock.java @@ -0,0 +1,13 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +public class Foo { + public int bar(int param) { + switch (param) { + default -> { + throw switch (param) { + default -> new ArithmeticException(); + }; + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideThrow.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideThrow.java new file mode 100644 index 000000000000..ce433565a076 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideThrow.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(Three param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableAssignment.java new file mode 100644 index 000000000000..24917447d86b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableAssignment.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + int x; + throw switch (param) { + default -> new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableDeclaration.java new file mode 100644 index 000000000000..ce433565a076 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideVariableDeclaration.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(Three param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideWhileLoopCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideWhileLoopCondition.java new file mode 100644 index 000000000000..c19601fb5f7b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideWhileLoopCondition.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + void methodA(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideYield.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideYield.java new file mode 100644 index 000000000000..19e76af9faf6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/afterSwitchInsideYield.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + int x = switch (param) { + case 1 -> 7; + default -> { + throw switch (param) { + default -> new RuntimeException("default"); + }; + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromAnonymousClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromAnonymousClass.java new file mode 100644 index 000000000000..3d27c0cdd125 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromAnonymousClass.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + new Runnable() { + public void run() { + throw new RuntimeException("runnable"); + } + }.run(); + throw new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromInnerSwitchExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromInnerSwitchExpression.java new file mode 100644 index 000000000000..58fbc4ebb44a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromInnerSwitchExpression.java @@ -0,0 +1,19 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + int x = switch (5) { + case 1: + throw new RuntimeException("one"); + case 2: + yield 3; + default: + throw new RuntimeException("default"); + }; + throw new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLambda.java new file mode 100644 index 000000000000..647478c16a95 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLambda.java @@ -0,0 +1,15 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + Runnable runnable = () -> { + throw new RuntimeException("runnable"); + }; + runnable.run(); + throw new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLocalClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLocalClass.java new file mode 100644 index 000000000000..9f05fa35a5cf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntLiftThrowFromLocalClass.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + class LocalClass { + public void fooBar() { + throw new RuntimeException("local classs"); + } + } + throw new RuntimeException("message"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertCondition.java new file mode 100644 index 000000000000..1a837606d933 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertCondition.java @@ -0,0 +1,7 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + assert switch(param) { default -> throw new RuntimeException(); } : "message"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertMessage.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertMessage.java new file mode 100644 index 000000000000..10448b1e0be9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideAssertMessage.java @@ -0,0 +1,7 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + assert true : switch(param) { default -> throw new RuntimeException(); }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideClassField.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideClassField.java new file mode 100644 index 000000000000..ef8081ebbf70 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideClassField.java @@ -0,0 +1,5 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + int bar = switch(param) { default -> throw new RuntimeException(); }; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideConditionalExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideConditionalExpression.java new file mode 100644 index 000000000000..7f8060a51f47 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideConditionalExpression.java @@ -0,0 +1,7 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + int bar(int param, boolean b) { + return b? switch (param) { default -> throw new RuntimeException("default"); } : 7; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideDoWhileLoopCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideDoWhileLoopCondition.java new file mode 100644 index 000000000000..73c4b9053ab7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideDoWhileLoopCondition.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + do { + methodA(1); + } while (switch (param) { default -> throw new RuntimeException("default"); }) + } + void methodA(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForCondition.java new file mode 100644 index 000000000000..c038def235c5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForCondition.java @@ -0,0 +1,8 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + for (int i = 0; i == switch(param) { default -> throw new RuntimeException(); }; i++) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForInitialization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForInitialization.java new file mode 100644 index 000000000000..5d02ea6091cb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForInitialization.java @@ -0,0 +1,8 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + for (int i = switch(param) { default -> throw new RuntimeException(); }; i < 0; i++) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForUpdate.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForUpdate.java new file mode 100644 index 000000000000..b22af341f1fd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideForUpdate.java @@ -0,0 +1,8 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + for (int i = 0; i < 0; i = switch(param) { default -> throw new RuntimeException(); }) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideLocalClassField.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideLocalClassField.java new file mode 100644 index 000000000000..7eb052ec0c99 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideLocalClassField.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "false" + + +class Foo { + void bar() { + class Local { + int bar = switch(3) { default -> throw new RuntimeException(); }; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideNestedConditionalExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideNestedConditionalExpression.java new file mode 100644 index 000000000000..03ac41ca1697 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideNestedConditionalExpression.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + int bar(int param, boolean b) { + return m(b? switch (param) { default -> throw new RuntimeException("default"); } : 7); + } + int m(int x) { + return 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideSynchronizedExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideSynchronizedExpression.java new file mode 100644 index 000000000000..99acdbe8ac70 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideSynchronizedExpression.java @@ -0,0 +1,8 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + synchronized (switch (param) { default -> throw new RuntimeException("default"); }) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideTryResourceInitialization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideTryResourceInitialization.java new file mode 100644 index 000000000000..52ecb40e1128 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeDoesntSupportSwitchInsideTryResourceInitialization.java @@ -0,0 +1,8 @@ +// "Lift 'throw' out of 'switch' expression" "false" + +class Foo { + void bar(int param) { + try (java.io.InputStream resource = switch(param) { default -> throw new RuntimeException(); }) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftingThrowsKeepsComments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftingThrowsKeepsComments.java new file mode 100644 index 000000000000..a8c746b919bb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftingThrowsKeepsComments.java @@ -0,0 +1,19 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + // BEFORE STATEMENT + return /* INSIDE 0*/ switch /*INSIDE 1*/ (7) { + // BEFORE FIRST + case 1 -> throw new /*INSIDE 2*/ RuntimeException("one"); // TRAILING + // BETWEEN + default -> { + // BEFORE + throw new /*INSIDE 3*/ RuntimeException("default"); // TRAILING + // AFTER + } + // AFTER LAST + }; + // AFTER STATEMENT + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromCodeBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromCodeBlock.java new file mode 100644 index 000000000000..87048ba13a47 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromCodeBlock.java @@ -0,0 +1,13 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + { + throw new RuntimeException("then"); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromForLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromForLoop.java new file mode 100644 index 000000000000..74626a0c87fd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromForLoop.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + for (int i = 0; i < new java.util.Random().nextInt(); i++) { + throw new RuntimeException("for"); + } + throw new RuntimeException("default"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromIfClauses.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromIfClauses.java new file mode 100644 index 000000000000..4016807d2c5f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromIfClauses.java @@ -0,0 +1,15 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + if (true) { + throw new RuntimeException("then"); + } else { + throw new RuntimeException("else"); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatement.java new file mode 100644 index 000000000000..82d77318e1f5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatement.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + switch (5) { + case 1: + throw new RuntimeException("one"); + default: + throw new RuntimeException("default"); + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java new file mode 100644 index 000000000000..b7a67b66ea30 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromNestedSwitchStatementLabeledRuleWithoutBlock.java @@ -0,0 +1,13 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + return switch (param) { + default: + switch (param) { + case 1 -> throw new RuntimeException(); + default -> throw new RuntimeException(); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelBlockStatements.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelBlockStatements.java new file mode 100644 index 000000000000..602dbf840d34 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelBlockStatements.java @@ -0,0 +1,20 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + enum Two { + ONE, TWO; + } + int bar(Two param) { + return switch (param) { + case ONE -> { + throw new RuntimeException("1"); + } + case TWO -> { + throw new RuntimeException("2"); + } + default -> { + throw new RuntimeException("default"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelThrowStatements.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelThrowStatements.java new file mode 100644 index 000000000000..80baadf47a2c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchLabelThrowStatements.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + enum Three { + ONE, TWO; + } + int bar(Three param) { + return switch (param) { + case ONE -> throw new RuntimeException("1"); + case TWO -> throw new RuntimeException("2"); + default -> throw new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchStatement.java new file mode 100644 index 000000000000..92bd6b01fc78 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromSwitchStatement.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param, boolean b) { + return switch (param) { + case 1: + if (b) { + throw new RuntimeException("one"); + } + default: + throw new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromWhileLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromWhileLoop.java new file mode 100644 index 000000000000..a167652b2e0b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeLiftsThrowFromWhileLoop.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar() { + return switch (7) { + default -> { + while (new java.util.Random().nextBoolean()) { + throw new RuntimeException("while"); + } + throw new RuntimeException("default"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsFirstElem.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsFirstElem.java new file mode 100644 index 000000000000..f310c6b80ff5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsFirstElem.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + return switch (param) { + default -> throw new RuntimeException("default"); + } + a(); + } + int a() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsSecondElem.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsSecondElem.java new file mode 100644 index 000000000000..9b317cf86fa6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionAsSecondElem.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + return a() + switch (param) { + default -> throw new RuntimeException("default"); + }; + } + int a() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java new file mode 100644 index 000000000000..77317175ad5f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideSwitchLabeledRuleWithoutBlock.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +public class Foo { + public int bar(int param) { + switch (param) { + default -> call() + switch (param) { + default -> throw new ArithmeticException(); + }; + } + } + public int call() { + return 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java new file mode 100644 index 000000000000..475060f0b5bf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideBinaryExpressionInsideThenClauseWithoutBlock.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +public class Foo { + public int bar(int param) { + if (param==2) + return call(call(1), switch (param) { + default -> throw new ArithmeticException(); + }); + else { + return 1; + } + } + public int call(Object... param) { + return 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCall.java new file mode 100644 index 000000000000..e5e38ece748e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCall.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + parentMethod( + methodA(1), + switch (param) { default -> throw new RuntimeException("default"); }, + methodA(2) + ); + } + void parentMethod(int x, int y, int z) {} + void methodA(int x) {} + void methodB(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideCall.java new file mode 100644 index 000000000000..c13fac41afa5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideCall.java @@ -0,0 +1,21 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + parentMethod( + a(1), + nestedMethod( + b(2), + switch (param) { default -> throw new RuntimeException("default"); }, + c(3) + ), + d(4) + ); + } + void parentMethod(int x, int y, int z) {} + int nestedMethod(int x, int y, int z) {} + void a(int x) {} + void b(int x) {} + void c(int x) {} + void d(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideThrow.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideThrow.java new file mode 100644 index 000000000000..b790dcf1b664 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideCallInsideThrow.java @@ -0,0 +1,16 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + throw newException( + a(1), + switch (param) { default -> throw new RuntimeException("default"); }, + b(2) + ); + } + Exception newException(int x, int y, int z) { + return new RuntimeException(); + } + void a(int x) {} + void b(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForLoopBody.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForLoopBody.java new file mode 100644 index 000000000000..b6ed316c2608 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForLoopBody.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + for (int i = 0; i < 10; i++) { + int x = switch (param) { default -> throw new RuntimeException("default"); }; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForeachInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForeachInitializer.java new file mode 100644 index 000000000000..2bcd2fe2a5e2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideForeachInitializer.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + for (var item : switch (param) { default -> throw new RuntimeException("default");}) { + methodA(1); + } + } + void methodA(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideIfConfition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideIfConfition.java new file mode 100644 index 000000000000..2057acc00ceb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideIfConfition.java @@ -0,0 +1,13 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + if (switch (param) { default -> throw new RuntimeException("default"); }) { + methodA(1); + } else { + methodB(2); + } + } + void methodA(int x) {} + void methodB(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideMultipleVariablesDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideMultipleVariablesDeclaration.java new file mode 100644 index 000000000000..f3afb66f4dbb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideMultipleVariablesDeclaration.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + int a = 3, b, c = 4, d = switch (param) { + default -> throw new RuntimeException("default"); + }, e = 5; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpression.java new file mode 100644 index 000000000000..c4b594561c29 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpression.java @@ -0,0 +1,11 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + return a() + switch (param) { + default -> throw new RuntimeException("default"); + } + b(); + } + int a() {return 0;} + int b() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpressionInsideVariableDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpressionInsideVariableDeclaration.java new file mode 100644 index 000000000000..dcb24d457572 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsidePolyadicExpressionInsideVariableDeclaration.java @@ -0,0 +1,11 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(Three param) { + int x = a() + switch (param) { + default -> throw new RuntimeException("default"); + } + b(); + } + int a() {return 0;} + int b() {return 0;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideReturn.java new file mode 100644 index 000000000000..f6839b0b422f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideReturn.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + return switch (param) { + default -> throw new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideSwitchLabeledRuleWithoutBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideSwitchLabeledRuleWithoutBlock.java new file mode 100644 index 000000000000..b30adededc0d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideSwitchLabeledRuleWithoutBlock.java @@ -0,0 +1,11 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +public class Foo { + public int bar(int param) { + switch (param) { + default -> switch (param) { + default -> throw new ArithmeticException(); + }; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideThrow.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideThrow.java new file mode 100644 index 000000000000..8c491761eaa2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideThrow.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(Three param) { + throw switch (param) { + default -> throw new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableAssignment.java new file mode 100644 index 000000000000..8c6d060d93b8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableAssignment.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(int param) { + int x; + x = switch (param) { + default -> throw new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableDeclaration.java new file mode 100644 index 000000000000..3dd0eb78eb10 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideVariableDeclaration.java @@ -0,0 +1,9 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + int bar(Three param) { + int x = switch (param) { + default -> throw new RuntimeException("default"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideWhileLoopCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideWhileLoopCondition.java new file mode 100644 index 000000000000..1a93b48e0eca --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideWhileLoopCondition.java @@ -0,0 +1,10 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + while (switch (param) { default -> throw new RuntimeException("default"); }) { + methodA(1); + } + } + void methodA(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideYield.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideYield.java new file mode 100644 index 000000000000..def6d5231972 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression/beforeSwitchInsideYield.java @@ -0,0 +1,14 @@ +// "Lift 'throw' out of 'switch' expression" "true-preview" + +class Foo { + void bar(int param) { + int x = switch (param) { + case 1 -> 7; + default -> { + yield switch (param) { + default -> throw new RuntimeException("default"); + }; + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFixTest.java new file mode 100644 index 000000000000..ebb9c54fa388 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/quickfix/LiftThrowOutOfSwitchExpressionFixTest.java @@ -0,0 +1,11 @@ +// Copyright 2000-2025 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.LightQuickFixParameterizedTestCase; + +public class LiftThrowOutOfSwitchExpressionFixTest extends LightQuickFixParameterizedTestCase { + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/liftThrowOutOfSwitchExpression"; + } +}