public ExprT balanceOnOperationChange()

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;
  }