All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.siyeh.ig.psiutils.ParenthesesUtils Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition java-analysis-impl library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.siyeh.ig.psiutils;

import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;

public class ParenthesesUtils {

  public static final Map tokenMap = new HashMap();

  private ParenthesesUtils() {}

  public static final int PARENTHESIZED_PRECEDENCE = 0;
  public static final int LITERAL_PRECEDENCE = 0;
  public static final int METHOD_CALL_PRECEDENCE = 1;
  public static final int POSTFIX_PRECEDENCE = 2;
  public static final int PREFIX_PRECEDENCE = 3;
  public static final int TYPE_CAST_PRECEDENCE = 4;
  public static final int MULTIPLICATIVE_PRECEDENCE = 5;
  public static final int ADDITIVE_PRECEDENCE = 6;
  public static final int SHIFT_PRECEDENCE = 7;
  public static final int RELATIONAL_PRECEDENCE = 8;
  public static final int EQUALITY_PRECEDENCE = 9;
  public static final int BINARY_AND_PRECEDENCE = 10;
  public static final int BINARY_XOR_PRECEDENCE = 11;
  public static final int BINARY_OR_PRECEDENCE = 12;
  public static final int AND_PRECEDENCE = 13;
  public static final int OR_PRECEDENCE = 14;
  public static final int CONDITIONAL_PRECEDENCE = 15;
  public static final int ASSIGNMENT_PRECEDENCE = 16;
  public static final int NUM_PRECEDENCES = 17;

  private static final Map s_binaryOperatorPrecedence = new HashMap(NUM_PRECEDENCES);


  static {
    tokenMap.put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS);
    tokenMap.put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS);
    tokenMap.put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK);
    tokenMap.put(JavaTokenType.DIVEQ, JavaTokenType.DIV);
    tokenMap.put(JavaTokenType.ANDEQ, JavaTokenType.AND);
    tokenMap.put(JavaTokenType.OREQ, JavaTokenType.OR);
    tokenMap.put(JavaTokenType.XOREQ, JavaTokenType.XOR);
    tokenMap.put(JavaTokenType.PERCEQ, JavaTokenType.PERC);
    tokenMap.put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT);
    tokenMap.put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT);
    tokenMap.put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT);
  }
  
  static {
    s_binaryOperatorPrecedence.put(JavaTokenType.PLUS, ADDITIVE_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.MINUS, ADDITIVE_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.ASTERISK, MULTIPLICATIVE_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.DIV, MULTIPLICATIVE_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.PERC, MULTIPLICATIVE_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.ANDAND, AND_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.OROR, OR_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.AND, BINARY_AND_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.OR, BINARY_OR_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.XOR, BINARY_XOR_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.LTLT, SHIFT_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.GTGT, SHIFT_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.GTGTGT, SHIFT_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.GT, RELATIONAL_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.GE, RELATIONAL_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.LT, RELATIONAL_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.LE, RELATIONAL_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.EQEQ, EQUALITY_PRECEDENCE);
    s_binaryOperatorPrecedence.put(JavaTokenType.NE, EQUALITY_PRECEDENCE);
  }

  @Nullable public static PsiElement getParentSkipParentheses(PsiElement element) {
    PsiElement parent = element.getParent();
    while (parent instanceof PsiParenthesizedExpression || parent instanceof PsiTypeCastExpression) {
      parent = parent.getParent();
    }
    return parent;
  }

  @Nullable
  public static PsiExpression stripParentheses(@Nullable PsiExpression expression) {
    while (expression instanceof PsiParenthesizedExpression) {
      final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression;
      expression = parenthesizedExpression.getExpression();
    }
    return expression;
  }

  public static boolean isCommutativeOperator(@NotNull IElementType token) {
    return !(token.equals(JavaTokenType.MINUS) ||
             token.equals(JavaTokenType.DIV) ||
             token.equals(JavaTokenType.PERC) ||
             token.equals(JavaTokenType.LTLT) ||
             token.equals(JavaTokenType.GTGT) ||
             token.equals(JavaTokenType.GTGTGT));
  }

  public static boolean isAssociativeOperation(PsiPolyadicExpression expression) {
    final IElementType tokenType = expression.getOperationTokenType();
    final PsiType type = expression.getType();
    final PsiPrimitiveType primitiveType;
    if (type instanceof PsiClassType) {
      primitiveType = PsiPrimitiveType.getUnboxedType(type);
      if (primitiveType == null) {
        return false;
      }
    } else if (type instanceof PsiPrimitiveType) {
      primitiveType = (PsiPrimitiveType)type;
    } else {
      return false;
    }
    if (JavaTokenType.PLUS == tokenType || JavaTokenType.ASTERISK == tokenType) {
      return primitiveType != PsiType.FLOAT && primitiveType != PsiType.DOUBLE;
    } else if (JavaTokenType.EQEQ == tokenType || JavaTokenType.NE == tokenType) {
      return primitiveType == PsiType.BOOLEAN;
    } else if (JavaTokenType.AND == tokenType || JavaTokenType.OR == tokenType || JavaTokenType.XOR == tokenType) {
      return true;
    } else if (JavaTokenType.OROR == tokenType || JavaTokenType.ANDAND == tokenType) {
      return true;
    }
    return false;
  }

  public static int getPrecedence(PsiExpression expression) {
    if (expression instanceof PsiThisExpression ||
        expression instanceof PsiLiteralExpression ||
        expression instanceof PsiSuperExpression ||
        expression instanceof PsiClassObjectAccessExpression ||
        expression instanceof PsiArrayAccessExpression ||
        expression instanceof PsiArrayInitializerExpression) {
      return LITERAL_PRECEDENCE;
    }
    if (expression instanceof PsiReferenceExpression) {
      final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
      if (referenceExpression.getQualifier() != null) {
        return METHOD_CALL_PRECEDENCE;
      }
      else {
        return LITERAL_PRECEDENCE;
      }
    }
    if (expression instanceof PsiMethodCallExpression || expression instanceof PsiNewExpression) {
      return METHOD_CALL_PRECEDENCE;
    }
    if (expression instanceof PsiTypeCastExpression) {
      return TYPE_CAST_PRECEDENCE;
    }
    if (expression instanceof PsiPrefixExpression) {
      return PREFIX_PRECEDENCE;
    }
    if (expression instanceof PsiPostfixExpression) {
      return POSTFIX_PRECEDENCE;
    }
    if (expression instanceof PsiPolyadicExpression) {
      final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
      return getPrecedenceForOperator(polyadicExpression.getOperationTokenType());
    }
    if (expression instanceof PsiInstanceOfExpression) {
      return RELATIONAL_PRECEDENCE;
    }
    if (expression instanceof PsiConditionalExpression) {
      return CONDITIONAL_PRECEDENCE;
    }
    if (expression instanceof PsiAssignmentExpression) {
      return ASSIGNMENT_PRECEDENCE;
    }
    if (expression instanceof PsiParenthesizedExpression) {
      return PARENTHESIZED_PRECEDENCE;
    }
    return -1;
  }

  public static int getPrecedenceForOperator(@NotNull IElementType operator) {
    final Integer precedence = s_binaryOperatorPrecedence.get(operator);
    if (precedence == null) {
      throw new IllegalArgumentException("unknown operator: " + operator);
    }
    return precedence.intValue();
  }

  public static void removeParentheses(@NotNull PsiExpression expression, boolean ignoreClarifyingParentheses) {
    if (expression instanceof PsiMethodCallExpression) {
      final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression;
      removeParensFromMethodCallExpression(methodCall, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiReferenceExpression) {
      final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
      removeParensFromReferenceExpression(referenceExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiNewExpression) {
      final PsiNewExpression newExpression = (PsiNewExpression)expression;
      removeParensFromNewExpression(newExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiAssignmentExpression) {
      final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression;
      removeParensFromAssignmentExpression(assignmentExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiArrayInitializerExpression) {
      final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)expression;
      removeParensFromArrayInitializerExpression(arrayInitializerExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiTypeCastExpression) {
      final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)expression;
      removeParensFromTypeCastExpression(typeCastExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiArrayAccessExpression) {
      final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)expression;
      removeParensFromArrayAccessExpression(arrayAccessExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiPrefixExpression) {
      final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression;
      removeParensFromPrefixExpression(prefixExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiPostfixExpression) {
      final PsiPostfixExpression postfixExpression = (PsiPostfixExpression)expression;
      removeParensFromPostfixExpression(postfixExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiPolyadicExpression) {
      final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
      removeParensFromPolyadicExpression(polyadicExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiInstanceOfExpression) {
      final PsiInstanceOfExpression instanceofExpression = (PsiInstanceOfExpression)expression;
      removeParensFromInstanceOfExpression(instanceofExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiConditionalExpression) {
      final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)expression;
      removeParensFromConditionalExpression(conditionalExpression, ignoreClarifyingParentheses);
    }
    if (expression instanceof PsiParenthesizedExpression) {
      final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression;
      removeParensFromParenthesizedExpression(parenthesizedExpression, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromReferenceExpression(@NotNull PsiReferenceExpression referenceExpression,
                                                          boolean ignoreClarifyingParentheses) {
    final PsiExpression qualifier = referenceExpression.getQualifierExpression();
    if (qualifier != null) {
      removeParentheses(qualifier, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromParenthesizedExpression(@NotNull PsiParenthesizedExpression parenthesizedExpression,
                                                              boolean ignoreClarifyingParentheses) {
    final PsiExpression body = parenthesizedExpression.getExpression();
    if (body == null) {
      parenthesizedExpression.delete();
      return;
    }
    final PsiElement parent = parenthesizedExpression.getParent();
    if (!(parent instanceof PsiExpression) || parent instanceof PsiParenthesizedExpression ||
        parent instanceof PsiArrayInitializerExpression) {
      final PsiExpression newExpression = (PsiExpression)parenthesizedExpression.replace(body);
      removeParentheses(newExpression, ignoreClarifyingParentheses);
      return;
    }
    else if (parent instanceof PsiArrayAccessExpression) {
      final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)parent;
      if (parenthesizedExpression == arrayAccessExpression.getIndexExpression()) {
        // use addAfter() + delete() instead of replace() to
        // workaround automatic insertion of parentheses by psi
        final PsiExpression newExpression = (PsiExpression)parent.addAfter(body, parenthesizedExpression);
        parenthesizedExpression.delete();
        removeParentheses(newExpression, ignoreClarifyingParentheses);
        return;
      }
    }
    final PsiExpression parentExpression = (PsiExpression)parent;
    final int parentPrecedence = getPrecedence(parentExpression);
    final int childPrecedence = getPrecedence(body);
    if (parentPrecedence < childPrecedence) {
      final PsiElement bodyParent = body.getParent();
      final PsiParenthesizedExpression newParenthesizedExpression = (PsiParenthesizedExpression)parenthesizedExpression.replace(bodyParent);
      final PsiExpression expression = newParenthesizedExpression.getExpression();
      if (expression != null) {
        removeParentheses(expression, ignoreClarifyingParentheses);
      }
    }
    else if (parentPrecedence == childPrecedence) {
      if (parentExpression instanceof PsiPolyadicExpression && body instanceof PsiPolyadicExpression) {
        final PsiPolyadicExpression parentPolyadicExpression = (PsiPolyadicExpression)parentExpression;
        final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType();
        final PsiPolyadicExpression bodyPolyadicExpression = (PsiPolyadicExpression)body;
        final IElementType bodyOperator = bodyPolyadicExpression.getOperationTokenType();
        final PsiType parentType = parentPolyadicExpression.getType();
        final PsiType bodyType = body.getType();
        if (parentType != null && parentType.equals(bodyType) && parentOperator.equals(bodyOperator)) {
          final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands();
          if (PsiTreeUtil.isAncestor(parentOperands[0], body, true) || isCommutativeOperator(bodyOperator)) {
            // use addAfter() + delete() instead of replace() to
            // workaround automatic insertion of parentheses by psi
            final PsiExpression newExpression = (PsiExpression)parent.addAfter(body, parenthesizedExpression);
            parenthesizedExpression.delete();
            removeParentheses(newExpression, ignoreClarifyingParentheses);
            return;
          }
        }
        if (ignoreClarifyingParentheses) {
          if (parentOperator.equals(bodyOperator)) {
            removeParentheses(body, ignoreClarifyingParentheses);
          }
        }
        else {
          final PsiExpression newExpression = (PsiExpression)parenthesizedExpression.replace(body);
          removeParentheses(newExpression, ignoreClarifyingParentheses);
        }
      }
      else {
        final PsiExpression newExpression = (PsiExpression)parenthesizedExpression.replace(body);
        removeParentheses(newExpression, ignoreClarifyingParentheses);
      }
    }
    else {
      if (ignoreClarifyingParentheses && parent instanceof PsiPolyadicExpression &&
          (body instanceof PsiPolyadicExpression || body instanceof PsiInstanceOfExpression)) {
        removeParentheses(body, ignoreClarifyingParentheses);
      }
      else {
        final PsiExpression newExpression = (PsiExpression)parenthesizedExpression.replace(body);
        removeParentheses(newExpression, ignoreClarifyingParentheses);
      }
    }
  }

  private static void removeParensFromConditionalExpression(@NotNull PsiConditionalExpression conditionalExpression,
                                                            boolean ignoreClarifyingParentheses) {
    final PsiExpression condition = conditionalExpression.getCondition();
    removeParentheses(condition, ignoreClarifyingParentheses);
    final PsiExpression thenBranch = conditionalExpression.getThenExpression();
    if (thenBranch != null) {
      removeParentheses(thenBranch, ignoreClarifyingParentheses);
    }
    final PsiExpression elseBranch = conditionalExpression.getElseExpression();
    if (elseBranch != null) {
      removeParentheses(elseBranch, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromInstanceOfExpression(@NotNull PsiInstanceOfExpression instanceofExpression,
                                                           boolean ignoreClarifyingParentheses) {
    final PsiExpression operand = instanceofExpression.getOperand();
    removeParentheses(operand, ignoreClarifyingParentheses);
  }

  private static void removeParensFromPolyadicExpression(@NotNull PsiPolyadicExpression polyadicExpression,
                                                         boolean ignoreClarifyingParentheses) {
    for (PsiExpression operand : polyadicExpression.getOperands()) {
      removeParentheses(operand, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromPostfixExpression(@NotNull PsiPostfixExpression postfixExpression,
                                                        boolean ignoreClarifyingParentheses) {
    final PsiExpression operand = postfixExpression.getOperand();
    removeParentheses(operand, ignoreClarifyingParentheses);
  }

  private static void removeParensFromPrefixExpression(@NotNull PsiPrefixExpression prefixExpression, boolean ignoreClarifyingParentheses) {
    final PsiExpression operand = prefixExpression.getOperand();
    if (operand != null) {
      removeParentheses(operand, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromArrayAccessExpression(@NotNull PsiArrayAccessExpression arrayAccessExpression,
                                                            boolean ignoreClarifyingParentheses) {
    final PsiExpression arrayExpression = arrayAccessExpression.getArrayExpression();
    removeParentheses(arrayExpression, ignoreClarifyingParentheses);
    final PsiExpression indexExpression = arrayAccessExpression.getIndexExpression();
    if (indexExpression != null) {
      removeParentheses(indexExpression, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromTypeCastExpression(@NotNull PsiTypeCastExpression typeCastExpression,
                                                         boolean ignoreClarifyingParentheses) {
    final PsiExpression operand = typeCastExpression.getOperand();
    if (operand != null) {
      removeParentheses(operand, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromArrayInitializerExpression(@NotNull PsiArrayInitializerExpression arrayInitializerExpression,
                                                                 boolean ignoreClarifyingParentheses) {
    final PsiExpression[] initializers = arrayInitializerExpression.getInitializers();
    for (final PsiExpression initializer : initializers) {
      removeParentheses(initializer, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromAssignmentExpression(@NotNull PsiAssignmentExpression assignment,
                                                           boolean ignoreClarifyingParentheses) {
    final PsiExpression lhs = assignment.getLExpression();
    final PsiExpression rhs = assignment.getRExpression();
    removeParentheses(lhs, ignoreClarifyingParentheses);
    if (rhs != null) {
      removeParentheses(rhs, ignoreClarifyingParentheses);
    }
  }

  private static void removeParensFromNewExpression(@NotNull PsiNewExpression newExpression, boolean ignoreClarifyingParentheses) {
    final PsiExpression[] dimensions = newExpression.getArrayDimensions();
    for (PsiExpression dimension : dimensions) {
      removeParentheses(dimension, ignoreClarifyingParentheses);
    }
    final PsiExpression qualifier = newExpression.getQualifier();
    if (qualifier != null) {
      removeParentheses(qualifier, ignoreClarifyingParentheses);
    }
    final PsiExpression arrayInitializer = newExpression.getArrayInitializer();
    if (arrayInitializer != null) {
      removeParentheses(arrayInitializer, ignoreClarifyingParentheses);
    }
    final PsiExpressionList argumentList = newExpression.getArgumentList();
    if (argumentList != null) {
      final PsiExpression[] arguments = argumentList.getExpressions();
      for (PsiExpression argument : arguments) {
        removeParentheses(argument, ignoreClarifyingParentheses);
      }
    }
  }

  private static void removeParensFromMethodCallExpression(@NotNull PsiMethodCallExpression methodCallExpression,
                                                           boolean ignoreClarifyingParentheses) {
    final PsiReferenceExpression target = methodCallExpression.getMethodExpression();
    final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
    final PsiExpression[] arguments = argumentList.getExpressions();
    removeParentheses(target, ignoreClarifyingParentheses);
    for (final PsiExpression argument : arguments) {
      removeParentheses(argument, ignoreClarifyingParentheses);
    }
  }

  public static boolean areParenthesesNeeded(PsiParenthesizedExpression expression, boolean ignoreClarifyingParentheses) {
    final PsiElement parent = expression.getParent();
    if (!(parent instanceof PsiExpression)) {
      return false;
    }
    final PsiExpression child = expression.getExpression();
    if (child == null) {
      return true;
    }
    if (parent instanceof PsiArrayAccessExpression) {
      final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)parent;
      final PsiExpression indexExpression = arrayAccessExpression.getIndexExpression();
      if (expression == indexExpression) {
        return false;
      }
    }
    return areParenthesesNeeded(child, (PsiExpression)parent, ignoreClarifyingParentheses);
  }

  public static boolean areParenthesesNeeded(PsiExpression expression, PsiExpression parentExpression,
                                             boolean ignoreClarifyingParentheses) {
    if (parentExpression instanceof PsiParenthesizedExpression || parentExpression instanceof PsiArrayInitializerExpression) {
      return false;
    }
    final int parentPrecedence = getPrecedence(parentExpression);
    final int childPrecedence = getPrecedence(expression);
    if (parentPrecedence > childPrecedence) {
      if (ignoreClarifyingParentheses) {
        if (expression instanceof PsiPolyadicExpression) {
          if (parentExpression instanceof PsiPolyadicExpression ||
              parentExpression instanceof PsiConditionalExpression ||
              parentExpression instanceof PsiInstanceOfExpression) {
            return true;
          }
        }
        else if (expression instanceof PsiInstanceOfExpression) {
          return true;
        }
      }
      return false;
    }
    if (parentExpression instanceof PsiPolyadicExpression && expression instanceof PsiPolyadicExpression) {
      final PsiPolyadicExpression parentPolyadicExpression = (PsiPolyadicExpression)parentExpression;
      final PsiType parentType = parentPolyadicExpression.getType();
      if (parentType == null) {
        return true;
      }
      final PsiPolyadicExpression childPolyadicExpression = (PsiPolyadicExpression)expression;
      final PsiType childType = childPolyadicExpression.getType();
      if (!parentType.equals(childType)) {
        return true;
      }
      if (childType.equalsToText(CommonClassNames.JAVA_LANG_STRING) &&
          !PsiTreeUtil.isAncestor(parentPolyadicExpression.getOperands()[0], childPolyadicExpression, true)) {
        final PsiExpression[] operands = childPolyadicExpression.getOperands();
        for (PsiExpression operand : operands) {
          if (!childType.equals(operand.getType())) {
            return true;
          }
        }
      }
      else if (childType.equals(PsiType.BOOLEAN)) {
        final PsiExpression[] operands = childPolyadicExpression.getOperands();
        for (PsiExpression operand : operands) {
          if (!PsiType.BOOLEAN.equals(operand.getType())) {
            return true;
          }
        }
      }
      final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType();
      final IElementType childOperator = childPolyadicExpression.getOperationTokenType();
      if (ignoreClarifyingParentheses) {
        if (!childOperator.equals(parentOperator)) {
          return true;
        }
      }
      final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands();
      if (!PsiTreeUtil.isAncestor(parentOperands[0], expression, false)) {
        if (!isAssociativeOperation(parentPolyadicExpression) ||
            JavaTokenType.DIV == childOperator || JavaTokenType.PERC == childOperator) {
          return true;
        }
      }
    }
    else if (parentExpression instanceof PsiConditionalExpression && expression instanceof PsiConditionalExpression) {
      final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)parentExpression;
      final PsiExpression condition = conditionalExpression.getCondition();
      return PsiTreeUtil.isAncestor(condition, expression, true);
    }
    return parentPrecedence < childPrecedence;
  }

  public static boolean areParenthesesNeeded(PsiJavaToken sign, PsiExpression rhs) {
    if (rhs instanceof PsiPolyadicExpression) {
      final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs;
      final int precedence1 = getPrecedenceForOperator(binaryExpression.getOperationTokenType());
      final IElementType signTokenType = sign.getTokenType();
      final IElementType newOperatorToken = tokenMap.get(signTokenType);
      final int precedence2 = getPrecedenceForOperator(newOperatorToken);
      return precedence1 >= precedence2 || !isCommutativeOperator(newOperatorToken);
    }
    else {
      return rhs instanceof PsiConditionalExpression;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy