diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java index a69cbfaf3b56..2b11fe90e90b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java @@ -176,14 +176,14 @@ public abstract class CodeBlockSurrounder { if (conditionParent instanceof PsiWhileStatement) { return new WhileConditionSurrounder(expression, (PsiWhileStatement)conditionParent); } - CodeBlockSurrounder parentSurrounder = forExpression(polyadicExpression); + CodeBlockSurrounder parentSurrounder = forExpressionSkipParentheses(polyadicExpression); if (parentSurrounder == null) return null; ParentContext parentContext = parentSurrounder.getExpectedParentContext(); if (parentContext != ParentContext.RETURN && parentContext != ParentContext.SIMPLE_IF_CONDITION) return null; return new AndOrToIfSurrounder(expression, polyadicExpression, parentSurrounder); } else if (type.equals(JavaTokenType.OROR) && polyadicExpression.getOperands()[0] != cur) { - CodeBlockSurrounder parentSurrounder = forExpression(polyadicExpression); + CodeBlockSurrounder parentSurrounder = forExpressionSkipParentheses(polyadicExpression); if (parentSurrounder == null) return null; ParentContext parentContext = parentSurrounder.getExpectedParentContext(); if (parentContext != ParentContext.RETURN) return null; @@ -191,7 +191,7 @@ public abstract class CodeBlockSurrounder { } } if (parent instanceof PsiConditionalExpression && ((PsiConditionalExpression)parent).getCondition() != cur) { - CodeBlockSurrounder parentSurrounder = forExpression((PsiConditionalExpression)parent); + CodeBlockSurrounder parentSurrounder = forExpressionSkipParentheses((PsiConditionalExpression)parent); if (parentSurrounder == null) return null; ParentContext parentContext = parentSurrounder.getExpectedParentContext(); if (parentContext != ParentContext.ASSIGNMENT && parentContext != ParentContext.RETURN) return null; @@ -253,6 +253,13 @@ public abstract class CodeBlockSurrounder { return null; } + private static @Nullable CodeBlockSurrounder forExpressionSkipParentheses(PsiExpression expression) { + while (expression.getParent() instanceof PsiParenthesizedExpression) { + expression = (PsiExpression)expression.getParent(); + } + return forExpression(expression); + } + private static boolean hasNameCollision(PsiElement declaration, PsiElement context) { if (declaration instanceof PsiDeclarationStatement) { PsiResolveHelper helper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper(); @@ -543,7 +550,8 @@ public abstract class CodeBlockSurrounder { @NotNull PsiStatement replace(@NotNull Project project, @NotNull PsiElementFactory factory) { boolean then = PsiTreeUtil.isAncestor(myConditional.getThenExpression(), myExpression, false); SurroundResult upstreamResult = myUpstream.surround(); - PsiConditionalExpression ternary = (PsiConditionalExpression)upstreamResult.getExpression(); + PsiConditionalExpression ternary = Objects.requireNonNull( + (PsiConditionalExpression)PsiUtil.skipParenthesizedExprDown(upstreamResult.getExpression())); PsiElement parent = PsiUtil.skipParenthesizedExprUp(ternary.getParent()); PsiStatement statement = upstreamResult.getAnchor(); if (parent instanceof PsiLocalVariable) { @@ -610,7 +618,8 @@ public abstract class CodeBlockSurrounder { int index = (int)StreamEx.of(operands).indexOf(o -> PsiTreeUtil.isAncestor(o, myExpression, false)) .orElseThrow(IllegalStateException::new); SurroundResult upstreamResult = myUpstream.surround(); - PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)upstreamResult.getExpression(); + PsiPolyadicExpression polyadicExpression = + (PsiPolyadicExpression)Objects.requireNonNull(PsiUtil.skipParenthesizedExprDown(upstreamResult.getExpression())); PsiStatement statement = upstreamResult.getAnchor(); PsiExpression operand = polyadicExpression.getOperands()[index]; PsiExpression lOperands = SplitConditionUtil.getLOperands(polyadicExpression, Objects.requireNonNull( diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/InsideTernary.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/InsideTernary.java new file mode 100644 index 000000000000..15a5bb11fc68 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/InsideTernary.java @@ -0,0 +1,8 @@ +import java.util.*; + +class Test { + + List getList(int x) { + return (x == 0 ? Collections.singletonList("0") : Collections.emptyList()); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/InsideTernary_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/InsideTernary_after.java new file mode 100644 index 000000000000..a3032f6033a3 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/InsideTernary_after.java @@ -0,0 +1,14 @@ +import java.util.*; + +class Test { + + List getList(int x) { + if (x == 0) { + List strings = new ArrayList<>(); + strings.add("0"); + return (strings); + } else { + return (Collections.emptyList()); + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/collections/ReplaceWithMutableCollectionIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/collections/ReplaceWithMutableCollectionIntentionTest.java index 211ffc9a6333..05f9598f711b 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/collections/ReplaceWithMutableCollectionIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/collections/ReplaceWithMutableCollectionIntentionTest.java @@ -65,6 +65,7 @@ public class ReplaceWithMutableCollectionIntentionTest extends IPPTestCase { public void testImmutableListAssignment() { assertIntentionNotAvailable(); } public void testImmutableSetVarArgArray() { doTest(); } public void testImmutableSetVarArgTernary() { doTest(); } + public void testInsideTernary() { doTest(); } @Override protected String getIntentionName() {