diff --git a/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchMigrationInspection.java b/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchMigrationInspection.java index bfb1a28a4bb7..e527065cfb6a 100644 --- a/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchMigrationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/EnhancedSwitchMigrationInspection.java @@ -78,7 +78,9 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc JavaBundle.message("inspection.switch.expression.migration.warn.only.on.expression"), true))); } - if (replacer.getType() == ReplacementType.Expression && replacer.getMaxNumberStatementsInBranch() != null && replacer.getMaxNumberStatementsInBranch() > 1) { + if (replacer.getType() == ReplacementType.Expression && + replacer.getMaxNumberStatementsInBranch() != null && + replacer.getMaxNumberStatementsInBranch() > 1) { int newMaxValue = replacer.getMaxNumberStatementsInBranch() - 1; fixes.add(LocalQuickFix.from(new UpdateInspectionOptionFix( EnhancedSwitchMigrationInspection.this, "myMaxNumberStatementsForBranch", @@ -226,7 +228,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc } StreamEx.ofTree((PsiElement)switchBlock, block -> Arrays.stream(block.getChildren())) .select(PsiBreakStatement.class) - .filter(breakStmt -> ControlFlowUtils.statementCompletesWithStatement(switchBlock, breakStmt) && breakStmt.findExitedStatement() == switchBlock) + .filter(breakStmt -> ControlFlowUtils.statementCompletesWithStatement(switchBlock, breakStmt) && + breakStmt.findExitedStatement() == switchBlock) .forEach(statement -> new CommentTracker().delete(statement)); return switchBlock; } @@ -237,7 +240,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc if (existsDefaultLabelElement(branch.myLabelStatement)) return true; } CompletenessResult completenessResult = evaluateSwitchCompleteness(switchStatement, true); - return completenessResult == CompletenessResult.COMPLETE_WITHOUT_UNCONDITIONAL || completenessResult == CompletenessResult.COMPLETE_WITH_UNCONDITIONAL; + return completenessResult == CompletenessResult.COMPLETE_WITHOUT_UNCONDITIONAL || + completenessResult == CompletenessResult.COMPLETE_WITH_UNCONDITIONAL; } private static boolean isConvertibleBranch(@NotNull OldSwitchStatementBranch branch, boolean hasNext) { @@ -255,7 +259,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc this.key = key; } - @Nls String getFixName() { + @Nls + String getFixName() { return JavaBundle.message(key); } } @@ -315,10 +320,11 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc * This method is used to rearrange branches. * Now it can change the order of branches or divide some branches into several separate branches. * For example, a null branch will be extracted from others. + * * @return rearranged branches */ private static @NotNull List rearrangeBranches(@NotNull List branches, - @NotNull PsiElement context) { + @NotNull PsiElement context) { if (branches.isEmpty()) { return branches; } @@ -344,6 +350,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc /** * This method is used to rearrange case elements. * Method is used by {@link #rearrangeBranches(List, PsiElement)}. + * * @param result - container, where sorted cases will be added */ private static void rearrangeCases(@NotNull SwitchBranch branch, @@ -375,7 +382,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc } private static @Nullable PsiCaseLabelElement findNullLabel(@NotNull List expressions) { - return ContainerUtil.find(expressions, label -> label instanceof PsiExpression literal && TypeConversionUtil.isNullType(literal.getType())); + return ContainerUtil.find(expressions, + label -> label instanceof PsiExpression literal && TypeConversionUtil.isNullType(literal.getType())); } private static final class ReturningSwitchReplacer implements SwitchReplacer { @@ -457,13 +465,13 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc */ private static @Nullable SwitchReplacer inspectReturningSwitch(@NotNull PsiStatement statement, - @NotNull List branches, - boolean isExhaustive, int maxNumberStatementsForExpression) { + @NotNull List branches, + boolean isExhaustive, int maxNumberStatementsForExpression) { PsiReturnStatement returnAfterSwitch = tryCast(PsiTreeUtil.getNextSiblingOfType(statement, PsiStatement.class), PsiReturnStatement.class); PsiThrowStatement throwAfterSwitch = tryCast(PsiTreeUtil.getNextSiblingOfType(statement, PsiStatement.class), PsiThrowStatement.class); - if (returnAfterSwitch == null && throwAfterSwitch==null && !isExhaustive) return null; + if (returnAfterSwitch == null && throwAfterSwitch == null && !isExhaustive) return null; List newBranches = new ArrayList<>(); boolean hasReturningBranch = false; boolean isInfo = false; @@ -500,7 +508,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc } int lastIndex = statements.length - 1; if (ContainerUtil.exists(statements, - st -> !PsiTreeUtil.findChildrenOfAnyType(st, PsiContinueStatement.class, PsiBreakStatement.class, PsiYieldStatement.class).isEmpty())) { + st -> !PsiTreeUtil.findChildrenOfAnyType(st, PsiContinueStatement.class, PsiBreakStatement.class, + PsiYieldStatement.class).isEmpty())) { return null; } PsiReturnStatement returnStmt = tryCast(statements[lastIndex], PsiReturnStatement.class); @@ -595,7 +604,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc private static @NotNull PsiStatement createYieldStatement(@NotNull PsiExpression expr) { Project project = expr.getProject(); PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); - return factory.createStatementFromText("yield " + StringUtil.trim(expr.getText()) + ";", expr); + return factory.createStatementFromText("yield " + StringUtil.trim(expr.getText()) + ";", expr); } private static final class SwitchExistingVariableReplacer implements SwitchReplacer { @@ -637,7 +646,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc PsiSwitchBlock replacement = generateEnhancedSwitch(switchStatement, myNewBranches, commentTracker, true); if (replacement == null) return; PsiExpression initializer = myVariableToAssign.getInitializer(); - if (myIsRightAfterDeclaration && isNotUsed(myVariableToAssign, switchStatement)) { + if (myIsRightAfterDeclaration && + (isNotUsed(myVariableToAssign, switchStatement) && isNotUsed(myVariableToAssign, replacement))) { if (initializer != null) { List sideEffectExpressions = SideEffectChecker.extractSideEffectExpressions(initializer); PsiStatement[] sideEffectStatements = StatementExtractor.generateStatements(sideEffectExpressions, initializer); @@ -661,10 +671,10 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc } } - private static boolean isNotUsed(@NotNull PsiVariable variable, @NotNull PsiStatement switchStatement) { + private static boolean isNotUsed(@NotNull PsiVariable variable, @NotNull PsiElement switchElement) { try { ControlFlow controlFlow = ControlFlowFactory - .getControlFlow(switchStatement, AllVariablesControlFlowPolicy.getInstance(), ControlFlowOptions.NO_CONST_EVALUATE); + .getControlFlow(switchElement, AllVariablesControlFlowPolicy.getInstance(), ControlFlowOptions.NO_CONST_EVALUATE); List references = ControlFlowUtil.getReadBeforeWrite(controlFlow); for (PsiReferenceExpression reference : references) { if (reference != null && reference.resolve() == variable) { @@ -695,8 +705,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc * */ private static @Nullable SwitchReplacer inspectVariableAssigningSwitch(@NotNull PsiStatement statement, - @NotNull List branches, - boolean isExhaustive, int maxNumberStatementsForExpression) { + @NotNull List branches, + boolean isExhaustive, int maxNumberStatementsForExpression) { PsiElement parent = statement.getParent(); PsiElement anchor = parent instanceof PsiLabeledStatement ? parent : statement; PsiLocalVariable assignedVariable = null; @@ -777,7 +787,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc return null; } } - return new SwitchExistingVariableReplacer(assignedVariable, statement, newBranches, isRightAfterDeclaration, isInfo, maxNumberStatementsInBranch); + return new SwitchExistingVariableReplacer(assignedVariable, statement, newBranches, isRightAfterDeclaration, isInfo, + maxNumberStatementsInBranch); } private static boolean existsDefaultLabelElement(@NotNull PsiSwitchLabelStatement statement) { @@ -795,10 +806,11 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc return SwitchBranch.createDefault(new SwitchRuleExpressionResult(initializer)); } PsiDeclarationStatement declaration = tryCast(assignedVariable.getParent(), PsiDeclarationStatement.class); - if (declaration == null || declaration.getParent()==null) return null; + if (declaration == null || declaration.getParent() == null) return null; try { final LocalsOrMyInstanceFieldsControlFlowPolicy policy = LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(); - final ControlFlow controlFlow = ControlFlowFactory.getInstance(declaration.getProject()).getControlFlow(declaration.getParent(), policy); + final ControlFlow controlFlow = + ControlFlowFactory.getInstance(declaration.getProject()).getControlFlow(declaration.getParent(), policy); final int switchStart = controlFlow.getStartOffset(statement); if (switchStart <= 0) { return null; @@ -818,7 +830,8 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc } private static boolean isRightAfterDeclaration(PsiElement anchor, PsiVariable assignedVariable) { - PsiDeclarationStatement declaration = tryCast(PsiTreeUtil.getPrevSiblingOfType(anchor, PsiStatement.class), PsiDeclarationStatement.class); + PsiDeclarationStatement declaration = + tryCast(PsiTreeUtil.getPrevSiblingOfType(anchor, PsiStatement.class), PsiDeclarationStatement.class); if (declaration != null) { PsiElement[] elements = declaration.getDeclaredElements(); if (elements.length == 1) { @@ -872,7 +885,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc * Suggest replacement with an enhanced switch statement */ private static @Nullable SwitchReplacer inspectReplacementWithStatement(@NotNull PsiStatement statement, - @NotNull List branches) { + @NotNull List branches) { for (int i = 0, size = branches.size(); i < size; i++) { OldSwitchStatementBranch branch = branches.get(i); if (!isConvertibleBranch(branch, i != size - 1) && @@ -914,12 +927,13 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc private final @Nullable PsiStatement @Nullable [] myOriginalResultStatements; - private SwitchStatementBranch(@Nullable PsiStatement @Nullable[] resultStatements) { + private SwitchStatementBranch(@Nullable PsiStatement @Nullable [] resultStatements) { myResultStatements = resultStatements; myOriginalResultStatements = null; } - private SwitchStatementBranch(@Nullable PsiStatement @Nullable[] resultStatements, @Nullable PsiStatement @Nullable[] originalResultStatements) { + private SwitchStatementBranch(@Nullable PsiStatement @Nullable [] resultStatements, + @Nullable PsiStatement @Nullable [] originalResultStatements) { myResultStatements = resultStatements; myOriginalResultStatements = originalResultStatements; } @@ -927,7 +941,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc @Override public String generate(CommentTracker ct, SwitchBranch branch) { @Nullable PsiStatement @Nullable [] resultStatements = myResultStatements; - if(resultStatements == null) return ""; + if (resultStatements == null) return ""; if (resultStatements.length == 1) { PsiStatement first = resultStatements[0]; if (first instanceof PsiExpressionStatement || first instanceof PsiBlockStatement || first instanceof PsiThrowStatement) { @@ -940,7 +954,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc if (element == null) continue; if (i == 0) { PsiElement current = getElementForComments(element, i); - if(current != null) { + if (current != null) { current = current.getPrevSibling(); } while (current instanceof PsiWhiteSpace || current instanceof PsiComment) { @@ -970,7 +984,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc private static void addNewLine(@NotNull StringBuilder sb) { String string = sb.toString(); String trimmed = string.trim(); - if(!string.substring(trimmed.length()).contains("\n")) { + if (!string.substring(trimmed.length()).contains("\n")) { sb.append("\n"); } } @@ -1192,7 +1206,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc public @Nullable PsiExpression getGuardExpression() { return myLabelStatement.getGuardExpression(); } - + private List getCaseLabelElements() { List branches = getWithFallthroughBranches(); Collections.reverse(branches); diff --git a/java/java-tests/testData/inspection/switchExpressionMigration/afterToExpressionWithReadBeforeWriteDefault.java b/java/java-tests/testData/inspection/switchExpressionMigration/afterToExpressionWithReadBeforeWriteDefault.java new file mode 100644 index 000000000000..1d991acfea63 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionMigration/afterToExpressionWithReadBeforeWriteDefault.java @@ -0,0 +1,15 @@ +// "Replace with 'switch' expression" "true-preview" +public final class A { + private void appendColored(String text) { + String style = getRegularAttributes(); + style = switch (text) { + case "failed" -> "ERROR_ATTRIBUTES"; + case "ignored" -> "IGNORE_ATTRIBUTES"; + default -> style; + }; + } + + private static String getRegularAttributes() { + return "REGULAR_ATTRIBUTES"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/switchExpressionMigration/beforeToExpressionWithReadBeforeWriteDefault.java b/java/java-tests/testData/inspection/switchExpressionMigration/beforeToExpressionWithReadBeforeWriteDefault.java new file mode 100644 index 000000000000..0f110960c0e1 --- /dev/null +++ b/java/java-tests/testData/inspection/switchExpressionMigration/beforeToExpressionWithReadBeforeWriteDefault.java @@ -0,0 +1,18 @@ +// "Replace with 'switch' expression" "true-preview" +public final class A { + private void appendColored(String text) { + String style = getRegularAttributes(); + switch (text) { + case "failed": + style = "ERROR_ATTRIBUTES"; + break; + case "ignored": + style = "IGNORE_ATTRIBUTES"; + break; + } + } + + private static String getRegularAttributes() { + return "REGULAR_ATTRIBUTES"; + } +} \ No newline at end of file