mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[java-inspections] SwitchStatementWithTooFewBranchesInspection: deal with side effects when unwrapping switch expression
GitOrigin-RevId: 65421bfe8edf8962161919991fbb9eaa3671f6d9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
338f8674e2
commit
62741ff30a
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.BlockUtils;
|
||||
@@ -21,7 +21,6 @@ import com.intellij.util.SmartList;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -157,26 +156,13 @@ public class UnwrapSwitchLabelFix implements LocalQuickFix {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps switch expression if it consists of single expression-branch; does nothing otherwise
|
||||
*
|
||||
* @param switchExpression expression to unwrap
|
||||
*/
|
||||
public static void unwrapExpression(@NotNull PsiSwitchExpression switchExpression) {
|
||||
unwrapExpression(switchExpression, null);
|
||||
}
|
||||
|
||||
private static void unwrapExpression(@NotNull PsiSwitchExpression switchExpression, @Nullable PsiCaseLabelElement label) {
|
||||
private static void unwrapExpression(@NotNull PsiSwitchExpression switchExpression, @NotNull PsiCaseLabelElement label) {
|
||||
PsiCodeBlock body = switchExpression.getBody();
|
||||
if (body == null) return;
|
||||
PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length != 1 || !(statements[0] instanceof PsiSwitchLabeledRuleStatement rule)) return;
|
||||
PsiStatement ruleBody = rule.getBody();
|
||||
if (!(ruleBody instanceof PsiExpressionStatement expressionStatement)) return;
|
||||
if (label == null) {
|
||||
new CommentTracker().replaceAndRestoreComments(switchExpression, expressionStatement.getExpression());
|
||||
return;
|
||||
}
|
||||
CodeBlockSurrounder surrounder = CodeBlockSurrounder.forExpression(switchExpression);
|
||||
if (surrounder != null) {
|
||||
CodeBlockSurrounder.SurroundResult surroundResult = surrounder.surround();
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Unwrap 'switch'" "true-preview"
|
||||
class X {
|
||||
int[] someArray;
|
||||
|
||||
native boolean someCondition(int i);
|
||||
|
||||
void test(int i) {
|
||||
--i;
|
||||
int x = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Unwrap 'switch'" "true-preview"
|
||||
class X {
|
||||
int[] someArray;
|
||||
|
||||
native boolean someCondition(int i);
|
||||
|
||||
void test(int i) {
|
||||
int x = <caret>switch (someArray[--i]) {
|
||||
default -> 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.siyeh.ig.controlflow;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ConvertSwitchToIfIntention;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.UnwrapSwitchLabelFix;
|
||||
import com.intellij.codeInspection.CleanupLocalInspectionTool;
|
||||
import com.intellij.codeInspection.CommonQuickFixBundle;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
@@ -31,7 +30,7 @@ import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.DelegatingFix;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.SwitchUtils;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -103,6 +102,46 @@ public class SwitchStatementWithTooFewBranchesInspection extends BaseInspection
|
||||
return new MinimumSwitchBranchesVisitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps switch expression if it consists of single expression-branch; does nothing otherwise
|
||||
*
|
||||
* @param switchExpression expression to unwrap
|
||||
*/
|
||||
private static void unwrapExpression(@NotNull PsiSwitchExpression switchExpression) {
|
||||
PsiExpression expression = getOnlyExpression(switchExpression);
|
||||
if (expression == null) return;
|
||||
PsiExpression selector = switchExpression.getExpression();
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
if (selector != null) {
|
||||
List<PsiExpression> expressions = SideEffectChecker.extractSideEffectExpressions(selector);
|
||||
if (!expressions.isEmpty()) {
|
||||
expressions.forEach(tracker::markUnchanged);
|
||||
PsiStatement[] sideEffects = StatementExtractor.generateStatements(expressions, selector);
|
||||
CodeBlockSurrounder surrounder = CodeBlockSurrounder.forExpression(switchExpression);
|
||||
if (surrounder != null) {
|
||||
CodeBlockSurrounder.SurroundResult result = surrounder.surround();
|
||||
PsiStatement anchor = result.getAnchor();
|
||||
for (PsiStatement effect : sideEffects) {
|
||||
anchor.getParent().addBefore(effect, anchor);
|
||||
}
|
||||
switchExpression = (PsiSwitchExpression)result.getExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
tracker.replaceAndRestoreComments(switchExpression, expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiExpression getOnlyExpression(@NotNull PsiSwitchExpression switchExpression) {
|
||||
PsiCodeBlock body = switchExpression.getBody();
|
||||
if (body == null) return null;
|
||||
PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length != 1 || !(statements[0] instanceof PsiSwitchLabeledRuleStatement rule)) return null;
|
||||
PsiStatement ruleBody = rule.getBody();
|
||||
if (!(ruleBody instanceof PsiExpressionStatement expressionStatement)) return null;
|
||||
return expressionStatement.getExpression();
|
||||
}
|
||||
|
||||
private class MinimumSwitchBranchesVisitor extends BaseInspectionVisitor {
|
||||
@Override
|
||||
public void visitSwitchExpression(@NotNull PsiSwitchExpression expression) {
|
||||
@@ -145,7 +184,11 @@ public class SwitchStatementWithTooFewBranchesInspection extends BaseInspection
|
||||
else {
|
||||
PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length == 1 && statements[0] instanceof PsiSwitchLabeledRuleStatement statement) {
|
||||
fixIsAvailable = SwitchUtils.isDefaultLabel(statement) && statement.getBody() instanceof PsiExpressionStatement;
|
||||
fixIsAvailable = SwitchUtils.isDefaultLabel(statement) &&
|
||||
statement.getBody() instanceof PsiExpressionStatement &&
|
||||
(block.getExpression() == null ||
|
||||
!SideEffectChecker.mayHaveSideEffects(block.getExpression()) ||
|
||||
CodeBlockSurrounder.canSurround(block.getExpression()));
|
||||
}
|
||||
else {
|
||||
fixIsAvailable = false;
|
||||
@@ -182,7 +225,7 @@ public class SwitchStatementWithTooFewBranchesInspection extends BaseInspection
|
||||
if (block instanceof PsiSwitchStatement) {
|
||||
ConvertSwitchToIfIntention.doProcessIntention((PsiSwitchStatement)block);
|
||||
} else if (block instanceof PsiSwitchExpression) {
|
||||
UnwrapSwitchLabelFix.unwrapExpression((PsiSwitchExpression)block);
|
||||
unwrapExpression((PsiSwitchExpression)block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user