mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Java. Code Formatting] IDEA-223507 Write tests for formatting conditional expressions
GitOrigin-RevId: b5ec80926db80796a899ccded49c38acb45c6dac
This commit is contained in:
committed by
intellij-monorepo-bot
parent
92bc9cbbb3
commit
9e3542c650
+4
-13
@@ -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);
|
||||
|
||||
+26
@@ -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
|
||||
}
|
||||
}
|
||||
+28
-3
@@ -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) {
|
||||
|
||||
+13
@@ -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());
|
||||
}
|
||||
}
|
||||
+13
@@ -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());
|
||||
}
|
||||
}
|
||||
+11
@@ -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());
|
||||
}
|
||||
}
|
||||
+11
@@ -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());
|
||||
}
|
||||
}
|
||||
+13
@@ -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();
|
||||
}
|
||||
}
|
||||
+13
@@ -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();
|
||||
}
|
||||
}
|
||||
+11
@@ -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();
|
||||
}
|
||||
}
|
||||
+11
@@ -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();
|
||||
}
|
||||
}
|
||||
+13
@@ -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();
|
||||
}
|
||||
}
|
||||
+13
@@ -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();
|
||||
}
|
||||
}
|
||||
+11
@@ -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();
|
||||
}
|
||||
}
|
||||
+11
@@ -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();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true
|
||||
? ("hello"
|
||||
+ "world")
|
||||
: ("goodbye"
|
||||
+ "world");
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true
|
||||
? ("hello"
|
||||
+ "world")
|
||||
: ("goodbye"
|
||||
+ "world");
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true ? ("hello"
|
||||
+ "world") : ("goodbye"
|
||||
+ "world");
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true ? ("hello"
|
||||
+ "world") : ("goodbye"
|
||||
+ "world");
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true
|
||||
? "hello"
|
||||
+ "world"
|
||||
: "goodbye"
|
||||
+ "world";
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true
|
||||
? "hello"
|
||||
+ "world"
|
||||
: "goodbye"
|
||||
+ "world";
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true ? "hello"
|
||||
+ "world" : "goodbye"
|
||||
+ "world";
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true ? "hello"
|
||||
+ "world" : "goodbye"
|
||||
+ "world";
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true
|
||||
? ("hello"
|
||||
+ "world")
|
||||
+ "!"
|
||||
: ("goodbye"
|
||||
+ "world")
|
||||
+ "!";
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true
|
||||
? ("hello"
|
||||
+ "world")
|
||||
+ "!"
|
||||
: ("goodbye"
|
||||
+ "world")
|
||||
+ "!";
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true ? ("hello"
|
||||
+ "world")
|
||||
+ "!" : ("goodbye"
|
||||
+ "world")
|
||||
+ "!";
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
public class A {
|
||||
void f() {
|
||||
String x = true ? ("hello"
|
||||
+ "world")
|
||||
+ "!" : ("goodbye"
|
||||
+ "world")
|
||||
+ "!";
|
||||
}
|
||||
}
|
||||
+17
@@ -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());
|
||||
}
|
||||
}
|
||||
+17
@@ -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());
|
||||
}
|
||||
}
|
||||
+15
@@ -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());
|
||||
}
|
||||
}
|
||||
+15
@@ -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());
|
||||
}
|
||||
}
|
||||
+17
@@ -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();
|
||||
}
|
||||
}
|
||||
+17
@@ -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();
|
||||
}
|
||||
}
|
||||
+15
@@ -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();
|
||||
}
|
||||
}
|
||||
+15
@@ -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();
|
||||
}
|
||||
}
|
||||
+89
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user