diff --git a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 606a73ffe77d..6026b17bd3bc 100644 --- a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -337,8 +337,8 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo } return Indent.getNoneIndent(); } - final ASTNode grandParent = skipParenthesesUp(parent.getTreeParent()); - if (grandParent != null && grandParent.getElementType() == JavaElementType.CONDITIONAL_EXPRESSION) { + + if (JavaFormatterConditionalExpressionUtil.isInsideConditionalExpression(parent)) { return Indent.getSpaceIndent(0, true); } } @@ -838,19 +838,10 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo return new LegacyChainedMethodCallsBlockBuilder(alignment, blockWrap, indent, mySettings, myJavaSettings, myFormattingMode).build(nodes); } - return new ChainMethodCallsBlockBuilder(alignment, blockWrap, indent, mySettings, myJavaSettings, myFormattingMode, shouldUseSpaceIndentInCallChain(node)).build(nodes); + return new ChainMethodCallsBlockBuilder(alignment, blockWrap, indent, mySettings, myJavaSettings, + myFormattingMode, JavaFormatterConditionalExpressionUtil.isInsideConditionalExpression(node)).build(nodes); } - private static boolean shouldUseSpaceIndentInCallChain(@NotNull ASTNode node) { - ASTNode parent = skipParenthesesUp(node); - if (parent == null) return false; - while (parent != null && parent.getElementType() == JavaElementType.REFERENCE_EXPRESSION) { - parent = parent.getTreeParent(); - if (parent == null || parent.getElementType() != JavaElementType.METHOD_CALL_EXPRESSION) return false; - parent = skipParenthesesUp(parent); - } - return parent != null && parent.getElementType() == JavaElementType.CONDITIONAL_EXPRESSION; - } private boolean shouldAlignChild(final @NotNull ASTNode child) { int role = getChildRole(child); diff --git a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt new file mode 100644 index 000000000000..34ab61156d93 --- /dev/null +++ b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt @@ -0,0 +1,26 @@ +// 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.psi.formatter.java + +import com.intellij.lang.ASTNode +import com.intellij.psi.impl.source.BasicJavaAstTreeUtil +import com.intellij.psi.impl.source.tree.ChildRole +import com.intellij.psi.impl.source.tree.CompositeElement +import com.intellij.psi.impl.source.tree.JavaElementType +import com.intellij.psi.tree.ParentAwareTokenSet + +internal object JavaFormatterConditionalExpressionUtil { + private val STOP_TOKENS = ParentAwareTokenSet.create(JavaElementType.METHOD, JavaElementType.LOCAL_VARIABLE, JavaElementType.METHOD) + + /** + * Checks if the given AST node is inside a conditional expression then or else branch. + */ + @JvmStatic + fun isInsideConditionalExpression(node : ASTNode) : Boolean { + val child = BasicJavaAstTreeUtil.getAncestorWithParentOfType(node, JavaElementType.CONDITIONAL_EXPRESSION, STOP_TOKENS) + if (child == null) return false + val parent = child.treeParent + if (parent !is CompositeElement) return false + val childRole = parent.getChildRole(child) + return childRole != ChildRole.CONDITION + } +} \ No newline at end of file diff --git a/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java b/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java index 72579e2037cd..b35c8c7838ee 100644 --- a/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java +++ b/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java @@ -301,9 +301,20 @@ public final class BasicJavaAstTreeUtil { return findParent(e, set); } - private static @Nullable ASTNode findParent(@NotNull ASTNode element, @NotNull IElementType type) { + private static @Nullable ASTNode findAncestorWithParentOfType(@NotNull ASTNode element, @NotNull IElementType type, @Nullable ParentAwareTokenSet stopAt) { + for (ASTNode currentElement = element, parent = element.getTreeParent(); parent != null; currentElement = parent, parent = parent.getTreeParent()) { + IElementType parentType = parent.getElementType(); + if (is(parentType, type)) return currentElement; + else if (stopAt != null && is(parentType, stopAt)) return null; + } + return null; + } + + private static @Nullable ASTNode findParent(@NotNull ASTNode element, @NotNull IElementType type, @Nullable ParentAwareTokenSet stopAt) { for (ASTNode parent = element.getTreeParent(); parent != null; parent = parent.getTreeParent()) { - if (is(parent.getElementType(), type)) return parent; + IElementType parentType = parent.getElementType(); + if (is(parentType, type)) return parent; + else if (stopAt != null && is(parentType, stopAt)) return null; } return null; } @@ -317,10 +328,24 @@ public final class BasicJavaAstTreeUtil { public static @Nullable ASTNode getParentOfType(@Nullable ASTNode e, @NotNull IElementType elementType) { + return getParentOfType(e, elementType, null); + } + + /** + * Finds the first ancestor which parent element type is equals to {@code elementType} + */ + public static @Nullable ASTNode getAncestorWithParentOfType(@Nullable ASTNode e, @NotNull IElementType elementType, @Nullable ParentAwareTokenSet stopAt) { if (e == null) { return null; } - return findParent(e, elementType); + return findAncestorWithParentOfType(e, elementType, stopAt); + } + + public static @Nullable ASTNode getParentOfType(@Nullable ASTNode e, @NotNull IElementType elementType, @Nullable ParentAwareTokenSet stopAt) { + if (e == null) { + return null; + } + return findParent(e, elementType, stopAt); } public static @Nullable ASTNode getMethodExpression(@Nullable ASTNode element) { diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnNewLine.java new file mode 100644 index 000000000000..64cf1e387670 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnNewLine.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true + ? (new StringBuilder() + .append("Hello") + .toString()) + : (new StringBuilder() + .append("World") + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnNewLine_after.java new file mode 100644 index 000000000000..859cc0b64afd --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnNewLine_after.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true + ? (new StringBuilder() + .append("Hello") + .toString()) + : (new StringBuilder() + .append("World") + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnPreviousLine.java new file mode 100644 index 000000000000..9d9ab7cccfbe --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnPreviousLine.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? (new StringBuilder() + .append("Hello") + .toString()) : (new StringBuilder() + .append("World") + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..144f51989039 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainInParensOperatorOnPreviousLine_after.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? (new StringBuilder() + .append("Hello") + .toString()) : (new StringBuilder() + .append("World") + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnNewLine.java new file mode 100644 index 000000000000..6ad1e43a57a9 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnNewLine.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true + ? new StringBuilder() + .append("Hello") + .toString() + : new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnNewLine_after.java new file mode 100644 index 000000000000..d20f34457f47 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnNewLine_after.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true + ? new StringBuilder() + .append("Hello") + .toString() + : new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnPreviousLine.java new file mode 100644 index 000000000000..57b007a4ec3f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnPreviousLine.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? new StringBuilder() + .append("Hello") + .toString() : new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..e1c0b5eeba3b --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainOperatorOnPreviousLine_after.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? new StringBuilder() + .append("Hello") + .toString() : new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnNewLine.java new file mode 100644 index 000000000000..16d241d66d8f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnNewLine.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true ? + (new StringBuilder() + .append("Hello")) + .toString() : + (new StringBuilder() + .append("World")) + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnNewLine_after.java new file mode 100644 index 000000000000..54453b857be9 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnNewLine_after.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true ? + (new StringBuilder() + .append("Hello")) + .toString() : + (new StringBuilder() + .append("World")) + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnPreviousLine.java new file mode 100644 index 000000000000..217db1a2dfd4 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnPreviousLine.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? (new StringBuilder() + .append("Hello")) + .toString() : (new StringBuilder() + .append("World")) + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..74241cb2aad6 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/callChainPartialInParensOperatorOnPreviousLine_after.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? (new StringBuilder() + .append("Hello")) + .toString() : (new StringBuilder() + .append("World")) + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnNewLine.java new file mode 100644 index 000000000000..4351f13a9d37 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnNewLine.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true + ? ("hello" + + "world") + : ("goodbye" + + "world"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnNewLine_after.java new file mode 100644 index 000000000000..737bcaef4a71 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnNewLine_after.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true + ? ("hello" + + "world") + : ("goodbye" + + "world"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnPreviousLine.java new file mode 100644 index 000000000000..1d4534f7aea2 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnPreviousLine.java @@ -0,0 +1,9 @@ +package org.example; + +public class A { + void f() { + String x = true ? ("hello" + + "world") : ("goodbye" + + "world"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..c011a88c13ad --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalInParensOperatorOnPreviousLine_after.java @@ -0,0 +1,9 @@ +package org.example; + +public class A { + void f() { + String x = true ? ("hello" + + "world") : ("goodbye" + + "world"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnNewLine.java new file mode 100644 index 000000000000..6eaa70ed792c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnNewLine.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true + ? "hello" + + "world" + : "goodbye" + + "world"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnNewLine_after.java new file mode 100644 index 000000000000..1d5751c25159 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnNewLine_after.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true + ? "hello" + + "world" + : "goodbye" + + "world"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnPreviousLine.java new file mode 100644 index 000000000000..25b173a743f2 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnPreviousLine.java @@ -0,0 +1,9 @@ +package org.example; + +public class A { + void f() { + String x = true ? "hello" + + "world" : "goodbye" + + "world"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..d57ee1750ba9 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalOperatorOnPreviousLine_after.java @@ -0,0 +1,9 @@ +package org.example; + +public class A { + void f() { + String x = true ? "hello" + + "world" : "goodbye" + + "world"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnNewLine.java new file mode 100644 index 000000000000..f8efb73bd064 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnNewLine.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true + ? ("hello" + + "world") + + "!" + : ("goodbye" + + "world") + + "!"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnNewLine_after.java new file mode 100644 index 000000000000..4f95dcea1fe3 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnNewLine_after.java @@ -0,0 +1,13 @@ +package org.example; + +public class A { + void f() { + String x = true + ? ("hello" + + "world") + + "!" + : ("goodbye" + + "world") + + "!"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnPreviousLine.java new file mode 100644 index 000000000000..51908725a8c1 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnPreviousLine.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? ("hello" + + "world") + + "!" : ("goodbye" + + "world") + + "!"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..920145537090 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/literalPartialInParensOperatorOnPreviousLine_after.java @@ -0,0 +1,11 @@ +package org.example; + +public class A { + void f() { + String x = true ? ("hello" + + "world") + + "!" : ("goodbye" + + "world") + + "!"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnNewLine.java new file mode 100644 index 000000000000..f3ba7c6bdfbd --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnNewLine.java @@ -0,0 +1,17 @@ +package org.example; + +public class A { + void f() { + String x = true + ? ("first ") + + "prefix" + + ((new StringBuilder() + .append("Hello")) + .toString()) + : ("alternative" + + "prefix") + + ((new StringBuilder() + .append("World")) + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnNewLine_after.java new file mode 100644 index 000000000000..94a3194f538c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnNewLine_after.java @@ -0,0 +1,17 @@ +package org.example; + +public class A { + void f() { + String x = true + ? ("first ") + + "prefix" + + ((new StringBuilder() + .append("Hello")) + .toString()) + : ("alternative" + + "prefix") + + ((new StringBuilder() + .append("World")) + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnPreviousLine.java new file mode 100644 index 000000000000..acfa389bec2b --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnPreviousLine.java @@ -0,0 +1,15 @@ +package org.example; + +public class A { + void f() { + String x = true ? ("first ") + + "prefix" + + ((new StringBuilder() + .append("Hello")) + .toString()) : ("alternative" + + "prefix") + + ((new StringBuilder() + .append("World")) + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..6012e3b6e9e4 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedInParensOperatorOnPreviousLine_after.java @@ -0,0 +1,15 @@ +package org.example; + +public class A { + void f() { + String x = true ? ("first ") + + "prefix" + + ((new StringBuilder() + .append("Hello")) + .toString()) : ("alternative" + + "prefix") + + ((new StringBuilder() + .append("World")) + .toString()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnNewLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnNewLine.java new file mode 100644 index 000000000000..7d7ab63db9ee --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnNewLine.java @@ -0,0 +1,17 @@ +package org.example; + +public class A { + void f() { + String x = true + ? "first " + + "prefix" + + new StringBuilder() + .append("Hello") + .toString() + : "alternative" + + "prefix" + + new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnNewLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnNewLine_after.java new file mode 100644 index 000000000000..95be3ca4a467 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnNewLine_after.java @@ -0,0 +1,17 @@ +package org.example; + +public class A { + void f() { + String x = true + ? "first " + + "prefix" + + new StringBuilder() + .append("Hello") + .toString() + : "alternative" + + "prefix" + + new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnPreviousLine.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnPreviousLine.java new file mode 100644 index 000000000000..fe90121d8985 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnPreviousLine.java @@ -0,0 +1,15 @@ +package org.example; + +public class A { + void f() { + String x = true ? "first " + + "prefix" + + new StringBuilder() + .append("Hello") + .toString() : "alternative" + + "prefix" + + new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnPreviousLine_after.java b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnPreviousLine_after.java new file mode 100644 index 000000000000..b9d41de9b1cd --- /dev/null +++ b/java/java-tests/testData/psi/formatter/conditionalExpression/mixedOperatorOnPreviousLine_after.java @@ -0,0 +1,15 @@ +package org.example; + +public class A { + void f() { + String x = true ? "first " + + "prefix" + + new StringBuilder() + .append("Hello") + .toString() : "alternative" + + "prefix" + + new StringBuilder() + .append("World") + .toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/psi/formatter/java/ConditionalExpressionFormatterTest.kt b/java/java-tests/testSrc/com/intellij/java/psi/formatter/java/ConditionalExpressionFormatterTest.kt new file mode 100644 index 000000000000..fe0d13977718 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/psi/formatter/java/ConditionalExpressionFormatterTest.kt @@ -0,0 +1,89 @@ +// 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.java.psi.formatter.java + +class ConditionalExpressionFormatterTest : JavaFormatterTestCase() { + override fun getBasePath(): String = "psi/formatter/conditionalExpression" + + fun testLiteralOperatorOnPreviousLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testLiteralOperatorOnNewLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testLiteralInParensOperatorOnPreviousLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testLiteralInParensOperatorOnNewLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testLiteralPartialInParensOperatorOnPreviousLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testLiteralPartialInParensOperatorOnNewLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testCallChainOperatorOnPreviousLine() { + doTest() + } + + fun testCallChainOperatorOnNewLine() { + doTest() + } + + fun testCallChainInParensOperatorOnPreviousLine() { + doTest() + } + + fun testCallChainInParensOperatorOnNewLine() { + doTest() + } + + fun testCallChainPartialInParensOperatorOnPreviousLine() { + doTest() + } + + fun testCallChainPartialInParensOperatorOnNewLine() { + doTest() + } + + fun testMixedOperatorOnPreviousLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testMixedOperatorOnNewLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testMixedInParensOperatorOnPreviousLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + fun testMixedInParensOperatorOnNewLine() { + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true + doTest() + } + + + override fun doTest() { + val fileNameBefore = getTestName(true) + val fileNameAfter = fileNameBefore + "_after" + doTest(fileNameBefore, fileNameAfter) + doTest(fileNameAfter, fileNameAfter) + super.doTest() + } +} \ No newline at end of file