diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 1157bef4cf0c..a347df8876f2 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -940,16 +940,16 @@ groupKey="group.names.language.level.specific.issues.and.migration.aids12" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING" implementationClass="com.intellij.codeInspection.EnhancedSwitchMigrationInspection" /> + - diff --git a/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchBackwardMigrationInspection.java b/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchBackwardMigrationInspection.java new file mode 100644 index 000000000000..3b7b175e2a17 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchBackwardMigrationInspection.java @@ -0,0 +1,294 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.codeInspection; + +import com.intellij.codeInsight.BlockUtils; +import com.intellij.openapi.project.Project; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.ig.psiutils.CommentTracker; +import com.siyeh.ig.psiutils.ControlFlowUtils; +import com.siyeh.ig.psiutils.SwitchUtils; +import one.util.streamex.StreamEx; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + +import static com.intellij.util.ObjectUtils.tryCast; + +public class EnhancedSwitchBackwardMigrationInspection extends AbstractBaseJavaLocalInspectionTool { + private static final SwitchMigrationCase[] ourCases = new SwitchMigrationCase[]{ + EnhancedSwitchBackwardMigrationInspection::inspectReturningSwitch, + EnhancedSwitchBackwardMigrationInspection::inspectVariableSavingSwitch, + EnhancedSwitchBackwardMigrationInspection::inspectSwitchStatement + }; + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + if (!PsiUtil.getLanguageLevel(holder.getFile()).isAtLeast(LanguageLevel.JDK_12_PREVIEW)) return PsiElementVisitor.EMPTY_VISITOR; + return new JavaElementVisitor() { + @Override + public void visitSwitchExpression(PsiSwitchExpression expression) { + if (findReplacer(expression) == null) return; + String message = InspectionsBundle.message("inspection.switch.expression.backward.expression.migration.inspection.name"); + holder.registerProblem(expression.getFirstChild(), message, new ReplaceWithOldStyleSwitchFix()); + } + + @Override + public void visitSwitchStatement(PsiSwitchStatement statement) { + if (findReplacer(statement) == null) return; + if (!SwitchUtils.isRuleFormatSwitch(statement)) return; + String message = InspectionsBundle.message("inspection.switch.expression.backward.statement.migration.inspection.name"); + holder.registerProblem(statement.getFirstChild(), message, new ReplaceWithOldStyleSwitchFix()); + } + }; + } + + private static Replacer findReplacer(@NotNull PsiSwitchBlock block) { + for (SwitchMigrationCase migrationCase : ourCases) { + Replacer replacer = migrationCase.suggestReplacer(block); + if (replacer != null) return replacer; + } + return null; + } + + private static Replacer inspectReturningSwitch(@NotNull PsiSwitchBlock switchBlock) { + if (!(switchBlock instanceof PsiSwitchExpression)) return null; + PsiReturnStatement returnStatement = tryCast(switchBlock.getParent(), PsiReturnStatement.class); + if (returnStatement == null) return null; + return new ReturningReplacer(returnStatement); + } + + private static Replacer inspectVariableSavingSwitch(@NotNull PsiSwitchBlock switchBlock) { + if (!(switchBlock instanceof PsiSwitchExpression)) return null; + PsiLocalVariable variable = tryCast(switchBlock.getParent(), PsiLocalVariable.class); + if (variable == null) return null; + return new VariableSavingReplacer(variable); + } + + private static Replacer inspectSwitchStatement(@NotNull PsiSwitchBlock switchBlock) { + if (!(switchBlock instanceof PsiSwitchStatement)) return null; + return new SwitchStatementReplacer(); + } + + private interface SwitchMigrationCase { + @Nullable + Replacer suggestReplacer(@NotNull PsiSwitchBlock switchBlock); + } + + private interface Replacer { + void replace(PsiSwitchBlock block); + } + + private static class ReplaceWithOldStyleSwitchFix implements LocalQuickFix { + + @Nls(capitalization = Nls.Capitalization.Sentence) + @NotNull + @Override + public String getFamilyName() { + return InspectionsBundle.message("inspection.replace.with.old.style.switch.statement.fix.name"); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PsiSwitchBlock switchBlock = tryCast(descriptor.getStartElement().getParent(), PsiSwitchBlock.class); + if (switchBlock == null) return; + Replacer replacer = findReplacer(switchBlock); + if (replacer == null) return; + replacer.replace(switchBlock); + } + } + + private static class ReturningReplacer implements Replacer { + private final PsiReturnStatement myReturnStatement; + + private ReturningReplacer(PsiReturnStatement returnStatement) {myReturnStatement = returnStatement;} + + @Override + public void replace(PsiSwitchBlock block) { + CommentTracker ct = new CommentTracker(); + PsiSwitchStatement switchStatement = new ReturnSwitchGenerator(block).generate(ct); + if (switchStatement == null) return; + ct.markUnchanged(block); + ct.replaceAndRestoreComments(myReturnStatement, switchStatement); + } + } + + private static class VariableSavingReplacer implements Replacer { + private final PsiLocalVariable myVariable; + + private VariableSavingReplacer(PsiLocalVariable variable) { + myVariable = variable; + } + + @Override + public void replace(PsiSwitchBlock block) { + PsiElementFactory factory = JavaPsiFacade.getInstance(block.getProject()).getElementFactory(); + PsiTypesUtil.replaceWithExplicitType(myVariable.getTypeElement()); + CommentTracker ct = new CommentTracker(); + PsiSwitchStatement switchStatement = new VarSavingSwitchGenerator(block, myVariable).generate(ct); + ct.markUnchanged(block); + PsiDeclarationStatement variableDeclaration = + (PsiDeclarationStatement)factory.createStatementFromText(myVariable.getTypeElement().getText() + " " + myVariable.getName() + ";", myVariable); + + ct.markUnchanged(switchStatement); + PsiStatement declaration = (PsiStatement)ct.replaceAndRestoreComments(myVariable.getParent(), variableDeclaration); + + BlockUtils.addAfter(declaration, switchStatement); + } + } + + private static class SwitchStatementReplacer implements Replacer { + @Override + public void replace(PsiSwitchBlock block) { + CommentTracker ct = new CommentTracker(); + PsiSwitchStatement switchStatement = new SwitchStatementGenerator(block).generate(ct); + if (switchStatement == null) return; + PsiElement newStatement = block.replace(switchStatement); + ct.insertCommentsBefore(newStatement); + } + } + + private static abstract class SwitchGenerator { + private final PsiSwitchBlock mySwitchBlock; + final PsiElementFactory myFactory; + + SwitchGenerator(PsiSwitchBlock switchBlock) {mySwitchBlock = switchBlock; + myFactory = JavaPsiFacade.getElementFactory(mySwitchBlock.getProject()); + } + + PsiSwitchStatement generate(CommentTracker mainCommentTracker) { + PsiSwitchBlock switchCopy = (PsiSwitchBlock)mySwitchBlock.copy(); + PsiExpression expression = switchCopy.getExpression(); + if (expression == null) return null; + PsiCodeBlock body = switchCopy.getBody(); + if (body == null) return null; + List rules = StreamEx.of(body.getStatements()) + .select(PsiSwitchLabeledRuleStatement.class) + .toList(); + List branchTrackers = new ArrayList<>(); + StringJoiner joiner = new StringJoiner("\n"); + for (PsiSwitchLabeledRuleStatement rule : rules) { + CommentTracker ct = new CommentTracker(); + branchTrackers.add(ct); + String generate = generateBranch(rule, ct, switchCopy); + joiner.add(generate); + mainCommentTracker.markUnchanged(rule); + } + String bodyText = joiner.toString(); + String switchText = "switch(" + mainCommentTracker.text(expression) + "){" + bodyText + "}"; + mainCommentTracker.grabComments(switchCopy); + PsiSwitchStatement newBlock = (PsiSwitchStatement)myFactory.createStatementFromText(switchText, mySwitchBlock); + PsiCodeBlock newBody = newBlock.getBody(); + assert newBody != null; + List branches = StreamEx.of(newBody.getStatements()) + .select(PsiSwitchLabelStatement.class) + .toList(); + if (branches.size() != branchTrackers.size()) return newBlock; + for (int i = 0; i < branches.size(); i++) { + PsiSwitchLabelStatement branch = branches.get(i); + branchTrackers.get(i).insertCommentsBefore(branch); + } + return newBlock; + } + + // rule changes inside, must be copied + private String generateBranch(PsiSwitchLabeledRuleStatement rule, + CommentTracker ct, + PsiSwitchBlock switchBlock) { + StreamEx.ofTree((PsiElement)rule, el -> StreamEx.of(el.getChildren())) + .select(PsiBreakStatement.class) + .filter(breakStatement -> breakStatement.getValueExpression() != null && breakStatement.findExitedElement() == switchBlock) + .forEach(breakStatement -> handleBreakInside(breakStatement, ct)); + PsiExpressionList caseValues = rule.getCaseValues(); + String caseValuesText = caseValues == null ? "" : ct.text(caseValues); + PsiStatement body = rule.getBody(); + String finalBody; + if (!(body instanceof PsiBlockStatement) && body != null) { + finalBody = generateExpressionBranch(body, ct); + } else { + finalBody = StreamEx.of(ControlFlowUtils.unwrapBlock(body)) + .map(el -> ct.text(el)) + .joining("\n"); + } + ct.grabComments(rule); + + + String prefix = rule.isDefaultCase() ? "default" : "case " + caseValuesText; + return prefix + ":" + finalBody; + } + + abstract void handleBreakInside(@NotNull PsiBreakStatement breakStatement, CommentTracker ct); + + abstract String generateExpressionBranch(@NotNull PsiStatement statement, CommentTracker ct); + } + + private static class ReturnSwitchGenerator extends SwitchGenerator { + ReturnSwitchGenerator(PsiSwitchBlock switchBlock) { + super(switchBlock); + } + + @Override + void handleBreakInside(@NotNull PsiBreakStatement breakStatement, CommentTracker ct) { + PsiExpression valueExpression = breakStatement.getValueExpression(); + assert valueExpression != null; + PsiStatement replacement = myFactory.createStatementFromText("return " + ct.text(valueExpression) + ";", breakStatement); + ct.markUnchanged(valueExpression); + ct.grabComments(breakStatement); + breakStatement.replace(replacement); + } + + @Override + String generateExpressionBranch(@NotNull PsiStatement statement, CommentTracker ct) { + return "return " + ct.text(statement); + } + } + + private static class VarSavingSwitchGenerator extends SwitchGenerator { + private final @NotNull PsiLocalVariable myVariable; + + VarSavingSwitchGenerator(PsiSwitchBlock switchBlock, @NotNull PsiLocalVariable variable) { + super(switchBlock); + myVariable = variable; + } + + @Override + void handleBreakInside(@NotNull PsiBreakStatement breakStatement, CommentTracker ct) { + PsiExpression valueExpression = breakStatement.getValueExpression(); + assert valueExpression != null; + String assignText = myVariable.getName() + " = " + valueExpression.getText() + ";\n"; + PsiStatement assignment = myFactory.createStatementFromText(assignText, valueExpression); + ct.markUnchanged(valueExpression); + ct.grabComments(breakStatement); + PsiStatement newAssignment = (PsiStatement)breakStatement.replace(assignment); + BlockUtils.addAfter(newAssignment, myFactory.createStatementFromText("break;", null)); + } + + @Override + String generateExpressionBranch(@NotNull PsiStatement statement, CommentTracker ct) { + return myVariable.getName() + " = " + ct.text(statement) + "\nbreak;"; + } + } + + private static class SwitchStatementGenerator extends SwitchGenerator { + SwitchStatementGenerator(PsiSwitchBlock switchBlock) { + super(switchBlock); + } + + @Override + void handleBreakInside(@NotNull PsiBreakStatement breakStatement, CommentTracker ct) { + // impossible, only if code is already broken, it can happen + } + + @Override + String generateExpressionBranch(@NotNull PsiStatement statement, CommentTracker ct) { + return ct.text(statement) + "\nbreak;"; + } + } +} diff --git a/java/java-impl/src/inspectionDescriptions/EnhancedSwitchBackwardMigration.html b/java/java-impl/src/inspectionDescriptions/EnhancedSwitchBackwardMigration.html new file mode 100644 index 000000000000..3011472d270b --- /dev/null +++ b/java/java-impl/src/inspectionDescriptions/EnhancedSwitchBackwardMigration.html @@ -0,0 +1,10 @@ + + +

+ Reports 'switch' statements, which can be replaced with enhanced 'switch' statement or expression. +

+

Available if the language level is at least Java 12 Preview.

+ +

New in 2019.1

+ + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturning.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturning.java new file mode 100644 index 000000000000..4621d588eb41 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturning.java @@ -0,0 +1,21 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + switch (x) { + case 1: + if (true) + return 0; + else + return 1; + case 2: + return 2; + case 3, 4: + System.out.println("asda"); + return 3; + default: + return 12; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturningComments.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturningComments.java new file mode 100644 index 000000000000..ff953d4fb6f0 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturningComments.java @@ -0,0 +1,25 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + /*1*//*3*//*4*//*6*//*7*//*8*//*18*//*2*/ + switch (x +/*5*/ x) {/*14*//*9*//*11*/ + case 1 +/*10*/ 1: + if (true /*12*/) + /*13*/ return 0; + else + return 1; + /*15*/ + /*16*/ + case 2: + return 2 +/*17*/ 2; + case 3, 4: + System.out.println("asda"); + return 3; + /*19*/ + default: + return 12 /*20*/ + 12; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturningWithNestedSwitch.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturningWithNestedSwitch.java new file mode 100644 index 000000000000..1f10c49719ef --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchReturningWithNestedSwitch.java @@ -0,0 +1,23 @@ +// "Replace with old style 'switch' statement" "true" + +class SwitchExpressionMigration { + private static void m(int x) { + switch (x) { + case 1: + if (true) { + return 0; + } else { + return 1; + } + case 2: + return switch (1) { + case 1 -> { + break 12; + } + default -> 55; + }; + default: + return 12; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchStatements.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchStatements.java new file mode 100644 index 000000000000..2f479b089a87 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchStatements.java @@ -0,0 +1,17 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static String m(int n) { + /*1*/ + /*3*/ + switch (n +/*cond*/ n) {/*case*/ + case 1: + System.out.println("a"/*2*/); + break; + case 2: + System.out.println("b"); + break; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigning.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigning.java new file mode 100644 index 000000000000..ccc0b5f93e2f --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigning.java @@ -0,0 +1,28 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + int x; + switch (x) { + case 1: + if (true) { + x = 0; + break; + } else { + x = 1; + break; + } + case 2: + x = 2; + break; + case 3, 4: + System.out.println("asda"); + x = 3; + break; + default: + x = 12; + break; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigningComments.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigningComments.java new file mode 100644 index 000000000000..0ac9b558f2f5 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigningComments.java @@ -0,0 +1,32 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + /*4*/ + /*1*/ + /*2*/ + /*3*/ + int x; + switch (x +/*cond*/ x) {/*5*/ + case 1: + if (true) { + x = 0; + break; + } else { + x = 1; + break; + } + case 2: + x = 2; + break; + case 3, 4: + System.out.println("asda"); + x = 3; + break; + default: + x = 12/*6*/; + break; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigningInferred.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigningInferred.java new file mode 100644 index 000000000000..677212e92a6c --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/afterSwitchVarAssigningInferred.java @@ -0,0 +1,16 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + int y; + switch (x) { + case 1: + y = 1; + break; + default: + y = 0; + break; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturning.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturning.java new file mode 100644 index 000000000000..1b7d717ffa57 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturning.java @@ -0,0 +1,20 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + return switch (x) { + case 1 -> {if (true) + break 0; + else + break 1; + } + case 2 -> 2; + case 3, 4 -> { + System.out.println("asda"); + break 3; + } + default -> 12; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturningComments.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturningComments.java new file mode 100644 index 000000000000..38f742e6ca0e --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturningComments.java @@ -0,0 +1,20 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + /*1*/return/*2*/ switch /*3*/(/*4*/x +/*5*/ x/*6*/) /*7*/ { + /*8*/case /*9*/ 1 +/*10*/ 1 -> /*11*/{if (true /*12*/) + /*13*/break /*14*/ 0; + else + break 1; + } + case/*15*/ 2 -> /*16*/2 +/*17*/ 2; + case 3, 4 -> { + System.out.println("asda"); + break 3; + } + /*18*/default/*19*/ -> 12 /*20*/ + 12; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturningWithNestedSwitch.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturningWithNestedSwitch.java new file mode 100644 index 000000000000..d6a1f4f3bc9b --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchReturningWithNestedSwitch.java @@ -0,0 +1,23 @@ +// "Replace with old style 'switch' statement" "true" + +class SwitchExpressionMigration { + private static void m(int x) { + return switch (x){ + case 1 -> { + if (true) { + break 0; + } + else { + break 1; + } + } + case 2 -> switch (1) { + case 1 -> { + break 12; + } + default -> 55; + }; + default -> 12; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchStatements.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchStatements.java new file mode 100644 index 000000000000..c294b253616b --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchStatements.java @@ -0,0 +1,12 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static String m(int n) { + switch (n +/*cond*/ n) { + /*1*/ + case /*case*/1 -> System.out.println("a"/*2*/); /*3*/ + case 2 -> System.out.println("b"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigning.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigning.java new file mode 100644 index 000000000000..d3d459a20067 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigning.java @@ -0,0 +1,20 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + int x = switch (x) { + case 1 -> {if (true) + break 0; + else + break 1; + } + case 2 -> 2; + case 3, 4 -> { + System.out.println("asda"); + break 3; + } + default -> 12; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigningComments.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigningComments.java new file mode 100644 index 000000000000..6ba44f865df7 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigningComments.java @@ -0,0 +1,20 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + int/*1*/ x /*2*/= /*3*/switch/*4*/ (x +/*cond*/ x) { + case 1 -> {if (true) + break /*5*/0; + else + break 1; + } + case 2 -> 2; + case 3, 4 -> { + System.out.println("asda"); + break 3; + } + default -> 12/*6*/; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigningInferred.java b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigningInferred.java new file mode 100644 index 000000000000..be0fb079ebc9 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionBackwardMigration/beforeSwitchVarAssigningInferred.java @@ -0,0 +1,11 @@ +// "Replace with old style 'switch' statement" "true" +import java.util.*; + +class SwitchExpressionMigration { + private static void m(int x) { + var y = switch (x) { + case 1 -> 1; + default -> 0; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/EnhancedSwitchBackwardMigrationInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/EnhancedSwitchBackwardMigrationInspectionTest.java new file mode 100644 index 000000000000..9de8fbc1968f --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/EnhancedSwitchBackwardMigrationInspectionTest.java @@ -0,0 +1,28 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.java.codeInspection; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.EnhancedSwitchBackwardMigrationInspection; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NotNull; + +public class EnhancedSwitchBackwardMigrationInspectionTest extends LightQuickFixParameterizedTestCase { + @NotNull + @Override + protected LocalInspectionTool[] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new EnhancedSwitchBackwardMigrationInspection() + }; + } + + @Override + protected String getBasePath() { + return "/inspection/switchExpressionBackwardMigration/"; + } + + @Override + protected LanguageLevel getLanguageLevel() { + return LanguageLevel.JDK_12_PREVIEW; + } +} diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index 5e7c63f374d1..c3274cb9b59a 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -1034,6 +1034,11 @@ inspection.switch.expression.migration.inspection.if.name=If statement can be re inspection.replace.with.switch.expression.fix.name=Replace with 'switch' expression inspection.replace.with.enhanced.switch.statement.fix.name=Replace with enhanced 'switch' statement +inspection.switch.expression.backward.migration.inspection.name='switch' expression can be replaced with old style 'switch' statement +inspection.switch.expression.backward.expression.migration.inspection.name='switch' expression can be replaced with old style 'switch' statement +inspection.switch.expression.backward.statement.migration.inspection.name='switch' statement can be replaced with old style 'switch' statement +inspection.replace.with.old.style.switch.statement.fix.name=Replace with old style 'switch' statement + inspection.duplicate.branches.in.switch.display.name=Duplicate branches in 'switch' statement inspection.duplicate.branches.in.switch.message=Duplicate branch in 'switch' statement inspection.duplicate.branches.in.switch.fix.family.name=Merge duplicate branches of 'switch' statement