Collect call expression nodes as a cycle instead of recursion

IDEA-291765

GitOrigin-RevId: caa05331ea83fb10f647ef00b8c0f7a4eb353511
This commit is contained in:
Georgii Ustinov
2023-11-29 11:35:43 +00:00
committed by intellij-monorepo-bot
parent 3e27184902
commit 47d91d14d3
@@ -20,10 +20,11 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.*;
import static com.intellij.psi.impl.PsiImplUtil.isTypeAnnotation;
@@ -34,6 +35,8 @@ public final class JavaFormatterUtil {
private static final TokenSet ASSIGNMENT_ELEMENT_TYPES = TokenSet
.create(JavaElementType.ASSIGNMENT_EXPRESSION, JavaElementType.LOCAL_VARIABLE, JavaElementType.FIELD);
private static final int CALL_EXPRESSION_DEPTH = 2500;
private JavaFormatterUtil() { }
/**
@@ -524,19 +527,31 @@ public final class JavaFormatterUtil {
*
*/
public static void collectCallExpressionNodes(@NotNull List<? super ASTNode> nodes, @NotNull ASTNode node) {
ASTNode child = node.getFirstChildNode();
while (child != null) {
if (!FormatterUtil.containsWhiteSpacesOnly(child)) {
IElementType type = child.getElementType();
if (type == JavaElementType.METHOD_CALL_EXPRESSION ||
type == JavaElementType.REFERENCE_EXPRESSION) {
collectCallExpressionNodes(nodes, child);
}
else {
nodes.add(child);
}
ArrayDeque<ASTNode> stack = new ArrayDeque<>(CALL_EXPRESSION_DEPTH);
stack.addLast(node.getFirstChildNode());
while (!stack.isEmpty()) {
if (stack.size() >= CALL_EXPRESSION_DEPTH) {
throw new IllegalStateException("Too long call chain! " + node);
}
child = child.getTreeNext();
ASTNode currentNode = stack.removeLast();
if (!FormatterUtil.containsWhiteSpacesOnly(currentNode)) {
IElementType type = currentNode.getElementType();
if (type == JavaElementType.METHOD_CALL_EXPRESSION ||
type == JavaElementType.REFERENCE_EXPRESSION) {
ASTNode firstChild = currentNode.getFirstChildNode();
currentNode = FormatterUtil.getNextNonWhitespaceSibling(currentNode);
ContainerUtil.addIfNotNull(stack, currentNode);
ContainerUtil.addIfNotNull(stack, firstChild);
}
else {
nodes.add(currentNode);
currentNode = FormatterUtil.getNextNonWhitespaceSibling(currentNode);
ContainerUtil.addIfNotNull(stack, currentNode);
}
} else {
currentNode = FormatterUtil.getNextNonWhitespaceSibling(currentNode);
ContainerUtil.addIfNotNull(stack, currentNode);
}
}
}
}