in projectional/src/main/java/jetbrains/jetpad/projectional/binOp/BinOpTransformer.java [107:150]
public ExprT balanceOnOperationChange(BinExprT expr) {
int exprPriority = getPriority(expr);
ExprT left = left(expr).get();
ExprT right = right(expr).get();
Associativity assoc = getAssociativity(expr);
if (isBinOp(left)) {
BinExprT leftExpr = asBinOp(left);
int leftPriority = getPriority(leftExpr);
if ((assoc == Associativity.LEFT && leftPriority < exprPriority) ||
(assoc == Associativity.RIGHT && leftPriority <= exprPriority)) {
expr = balanceDown(expr);
}
} else if (isBinOp(right)) {
BinExprT rightExpr = asBinOp(right);
int rightPriority = getPriority(rightExpr);
if ((assoc == Associativity.LEFT && rightPriority >= exprPriority) ||
(assoc == Associativity.RIGHT && rightPriority > exprPriority)) {
expr = balanceDown(expr);
}
}
ExprT parent = parent(expr);
assoc = getAssociativity(expr);
if (isBinOp(parent)) {
BinExprT parentExpr = asBinOp(parent);
int parentPriority = getPriority(parentExpr);
boolean isLeft = left == left(parentExpr).get();
if (isLeft &&
(assoc == Associativity.LEFT && exprPriority < parentPriority) ||
(assoc == Associativity.RIGHT && exprPriority <= parentPriority)) {
return balanceUp(expr);
}
if (!isLeft &&
(assoc == Associativity.LEFT && exprPriority <= parentPriority) ||
(assoc == Associativity.RIGHT && exprPriority < parentPriority)) {
return balanceUp(expr);
}
}
return expr;
}