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 !PsiType.FLOAT.equals(primitiveType) && !PsiType.DOUBLE.equals(primitiveType);
   } else if (JavaTokenType.EQEQ == tokenType || JavaTokenType.NE == tokenType) {
     return PsiType.BOOLEAN.equals(primitiveType);
   } 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 void translate(PsiPolyadicExpression element, TranslationContext ctx) {
   for (PsiExpression expression : element.getOperands()) {
     PsiJavaToken token = element.getTokenBeforeOperand(expression);
     if (token != null) {
       ctx.append(' ');
       JavaTokenTranslator.translate(token, ctx);
       ctx.append(' ');
     }
     ExpressionTranslator.translate(expression, ctx);
   }
 }
 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;
   }
 }
 @Nullable
 private String evaluate(PsiExpression expression, Map<String, Computable<String>> arguments) {
   if (expression instanceof PsiPolyadicExpression) {
     PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression) expression;
     if (binaryExpression.getOperationTokenType() == JavaTokenType.PLUS) {
       String r = "";
       for (PsiExpression op : binaryExpression.getOperands()) {
         String lhs = evaluate(op, arguments);
         if (lhs == null) return null;
         r += lhs;
       }
       return r;
     }
   } else if (expression instanceof PsiLiteralExpression) {
     final Object value = ((PsiLiteralExpression) expression).getValue();
     if (value instanceof String) {
       return (String) value;
     }
   } else if (expression instanceof PsiReferenceExpression) {
     final PsiElement result = ((PsiReferenceExpression) expression).resolve();
     if (result instanceof PsiParameter) {
       final String name = ((PsiParameter) result).getName();
       final Computable<String> arg = arguments.get(name);
       return arg == null ? null : arg.compute();
     }
     if (result instanceof PsiVariable) {
       final PsiExpression initializer = ((PsiVariable) result).getInitializer();
       if (initializer != null) {
         return evaluate(initializer, arguments);
       }
     }
   } else if (expression instanceof PsiMethodCallExpression) {
     final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
     final String callText = methodCall.getMethodExpression().getText();
     if (callText.equals("getTestName")) {
       final PsiExpression[] psiExpressions = methodCall.getArgumentList().getExpressions();
       if (psiExpressions.length == 1) {
         if ("true".equals(psiExpressions[0].getText()) && !StringUtil.isEmpty(myTestName)) {
           return UsefulTestCase.lowercaseFirstLetter(myTestName, true);
         }
         return myTestName;
       }
     }
   }
   if (expression != null) {
     myLogMessages.add("Failed to evaluate " + expression.getText());
   }
   return null;
 }
 private static boolean isPartOfLargerExpression(PsiPolyadicExpression expression) {
   if (expression.getOperands().length > 2) {
     return true;
   }
   final PsiElement containingElement = expression.getParent();
   if (containingElement instanceof PsiExpression) {
     final PsiExpression containingExpression = (PsiExpression) containingElement;
     if (!PsiUtil.isConstantExpression(containingExpression)) {
       return false;
     }
   } else {
     return false;
   }
   return true;
 }
 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;
 }
 @Nullable
 static PsiPolyadicExpression getSubexpression(
     PsiPolyadicExpression expression, PsiJavaToken token) {
   final PsiExpression[] operands = expression.getOperands();
   if (operands.length == 2) {
     return expression;
   }
   for (int i = 1; i < operands.length; i++) {
     final PsiExpression operand = operands[i];
     final PsiJavaToken currentToken = expression.getTokenBeforeOperand(operand);
     if (currentToken == token) {
       final String binaryExpressionText =
           operands[i - 1].getText() + ' ' + token.getText() + ' ' + operand.getText();
       final PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject());
       return (PsiPolyadicExpression)
           factory.createExpressionFromText(binaryExpressionText, expression);
     }
   }
   return null;
 }
 private static boolean polyadicExpressionsAreEquivalent(
     @NotNull PsiPolyadicExpression polyadicExpression1,
     @NotNull PsiPolyadicExpression polyadicExpression2) {
   final IElementType tokenType1 = polyadicExpression1.getOperationTokenType();
   final IElementType tokenType2 = polyadicExpression2.getOperationTokenType();
   if (!tokenType1.equals(tokenType2)) {
     return false;
   }
   final PsiExpression[] operands1 = polyadicExpression1.getOperands();
   final PsiExpression[] operands2 = polyadicExpression2.getOperands();
   if (operands1.length != operands2.length) {
     return false;
   }
   for (int i = 0, length = operands1.length; i < length; i++) {
     if (!expressionsAreEquivalent(operands1[i], operands2[i])) {
       return false;
     }
   }
   return true;
 }
 @Override
 public void visitPolyadicExpression(PsiPolyadicExpression expression) {
   super.visitPolyadicExpression(expression);
   if (!ExpressionUtils.hasStringType(expression)) {
     return;
   }
   final PsiExpression[] operands = expression.getOperands();
   for (PsiExpression operand : operands) {
     checkExpression(operand);
   }
 }
  @Override
  public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
    final PsiPolyadicExpression expression = SplitConditionUtil.findCondition(element, true, false);
    if (expression == null || expression.getOperands().length < 2) return false;

    PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
    if (!(parent instanceof PsiLambdaExpression)) return false;
    if (((PsiLambdaExpression) parent).getParameterList().getParametersCount() != 1) return false;
    parent = parent.getParent();

    if (!(parent instanceof PsiExpressionList)) return false;
    final PsiElement gParent = parent.getParent();
    if (!(gParent instanceof PsiMethodCallExpression)) return false;

    if (MergeFilterChainAction.isFilterCall((PsiMethodCallExpression) gParent)) {
      return true;
    }

    return false;
  }
 @Nullable
 private static PsiReferenceExpression getReferenceFromInstanceofExpression(
     PsiExpression expression) {
   if (expression instanceof PsiParenthesizedExpression) {
     final PsiParenthesizedExpression parenthesizedExpression =
         (PsiParenthesizedExpression) expression;
     return getReferenceFromInstanceofExpression(parenthesizedExpression.getExpression());
   } else if (expression instanceof PsiInstanceOfExpression) {
     final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression) expression;
     final PsiExpression operand =
         ParenthesesUtils.stripParentheses(instanceOfExpression.getOperand());
     if (!(operand instanceof PsiReferenceExpression)) {
       return null;
     }
     return (PsiReferenceExpression) operand;
   } else if (expression instanceof PsiPolyadicExpression) {
     final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression) expression;
     final IElementType tokenType = polyadicExpression.getOperationTokenType();
     if (JavaTokenType.OROR != tokenType) {
       return null;
     }
     final PsiExpression[] operands = polyadicExpression.getOperands();
     final PsiReferenceExpression referenceExpression =
         getReferenceFromInstanceofExpression(operands[0]);
     if (referenceExpression == null) {
       return null;
     }
     for (int i = 1, operandsLength = operands.length; i < operandsLength; i++) {
       if (!referencesEqual(
           referenceExpression, getReferenceFromInstanceofExpression(operands[i]))) {
         return null;
       }
     }
     return referenceExpression;
   } else {
     return null;
   }
 }
  @Override
  public boolean satisfiedBy(PsiElement element) {
    final PsiJavaToken token;
    if (element instanceof PsiJavaToken) {
      token = (PsiJavaToken) element;
    } else {
      final PsiElement prevSibling = element.getPrevSibling();
      if (prevSibling instanceof PsiJavaToken) {
        token = (PsiJavaToken) prevSibling;
      } else {
        return false;
      }
    }

    final PsiElement parent = element.getParent();
    if (!(parent instanceof PsiPolyadicExpression)) {
      return false;
    }
    final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression) parent;
    final PsiType type = polyadicExpression.getType();
    if (type == null || type.equalsToText("java.lang.String")) {
      // handled by JoinConcatenatedStringLiteralsIntention
      return false;
    }
    final PsiPolyadicExpression subexpression = getSubexpression(polyadicExpression, token);
    if (subexpression == null) {
      return false;
    }
    if (!isPartOfLargerExpression(polyadicExpression)) {
      // handled by ConstantExpressionIntention
      return false;
    }
    if (!PsiUtil.isConstantExpression(subexpression)) {
      return false;
    }
    final Object value = ExpressionUtils.computeConstantExpression(subexpression);
    return value != null;
  }
Exemple #13
0
  @NotNull
  public List<String> createConversions(
      @NotNull PsiPolyadicExpression expression, PsiType expectedType) {
    PsiExpression[] arguments = expression.getOperands();
    int length = arguments.length;
    List<String> conversions = new LinkedList<String>();

    List<PsiType> expectedTypes = Collections.nCopies(length, expectedType);
    List<PsiType> actualTypes = new LinkedList<PsiType>();

    for (PsiExpression e : arguments) actualTypes.add(e.getType());

    assert actualTypes.size() == expectedTypes.size() : "The type list must have the same length";

    for (int i = 0; i < actualTypes.size(); i++)
      conversions.add(i, createConversionForExpression(arguments[i], expectedTypes.get(i)));

    return conversions;
  }
 private boolean checkCondition(
     @Nullable PsiExpression condition,
     @NotNull PsiStatement context,
     List<PsiExpression> notUpdated) {
   if (condition == null) {
     return false;
   }
   if (PsiUtil.isConstantExpression(condition) || PsiKeyword.NULL.equals(condition.getText())) {
     return true;
   }
   if (condition instanceof PsiInstanceOfExpression) {
     final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression) condition;
     final PsiExpression operand = instanceOfExpression.getOperand();
     return checkCondition(operand, context, notUpdated);
   } else if (condition instanceof PsiParenthesizedExpression) {
     // catch stuff like "while ((x)) { ... }"
     final PsiExpression expression = ((PsiParenthesizedExpression) condition).getExpression();
     return checkCondition(expression, context, notUpdated);
   } else if (condition instanceof PsiPolyadicExpression) {
     // while (value != x) { ... }
     // while (value != (x + y)) { ... }
     // while (b1 && b2) { ... }
     final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression) condition;
     for (PsiExpression operand : polyadicExpression.getOperands()) {
       if (!checkCondition(operand, context, notUpdated)) {
         return false;
       }
     }
     return true;
   } else if (condition instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) condition;
     final PsiElement element = referenceExpression.resolve();
     if (element instanceof PsiField) {
       final PsiField field = (PsiField) element;
       final PsiType type = field.getType();
       if (field.hasModifierProperty(PsiModifier.FINAL) && type.getArrayDimensions() == 0) {
         if (field.hasModifierProperty(PsiModifier.STATIC)) {
           return true;
         }
         final PsiExpression qualifier = referenceExpression.getQualifierExpression();
         if (qualifier == null) {
           return true;
         } else if (checkCondition(qualifier, context, notUpdated)) {
           return true;
         }
       }
     } else if (element instanceof PsiVariable) {
       final PsiVariable variable = (PsiVariable) element;
       if (variable.hasModifierProperty(PsiModifier.FINAL)) {
         // final variables cannot be updated, don't bother to
         // flag them
         return true;
       } else if (element instanceof PsiLocalVariable || element instanceof PsiParameter) {
         if (!VariableAccessUtils.variableIsAssigned(variable, context)) {
           notUpdated.add(referenceExpression);
           return true;
         }
       }
     }
   } else if (condition instanceof PsiPrefixExpression) {
     final PsiPrefixExpression prefixExpression = (PsiPrefixExpression) condition;
     final IElementType tokenType = prefixExpression.getOperationTokenType();
     if (JavaTokenType.EXCL.equals(tokenType)
         || JavaTokenType.PLUS.equals(tokenType)
         || JavaTokenType.MINUS.equals(tokenType)) {
       final PsiExpression operand = prefixExpression.getOperand();
       return checkCondition(operand, context, notUpdated);
     }
   } else if (condition instanceof PsiArrayAccessExpression) {
     // Actually the contents of the array could change nevertheless
     // if it is accessed through a different reference like this:
     //   int[] local_ints = new int[]{1, 2};
     //   int[] other_ints = local_ints;
     //   while (local_ints[0] > 0) { other_ints[0]--; }
     //
     // Keep this check?
     final PsiArrayAccessExpression accessExpression = (PsiArrayAccessExpression) condition;
     final PsiExpression indexExpression = accessExpression.getIndexExpression();
     return checkCondition(indexExpression, context, notUpdated)
         && checkCondition(accessExpression.getArrayExpression(), context, notUpdated);
   } else if (condition instanceof PsiConditionalExpression) {
     final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression) condition;
     final PsiExpression thenExpression = conditionalExpression.getThenExpression();
     final PsiExpression elseExpression = conditionalExpression.getElseExpression();
     if (thenExpression == null || elseExpression == null) {
       return false;
     }
     return checkCondition(conditionalExpression.getCondition(), context, notUpdated)
         && checkCondition(thenExpression, context, notUpdated)
         && checkCondition(elseExpression, context, notUpdated);
   } else if (condition instanceof PsiThisExpression) {
     return true;
   } else if (condition instanceof PsiMethodCallExpression && !ignoreIterators) {
     final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) condition;
     if (!IteratorUtils.isCallToHasNext(methodCallExpression)) {
       return false;
     }
     final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
     final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
     if (qualifierExpression instanceof PsiReferenceExpression) {
       final PsiReferenceExpression referenceExpression =
           (PsiReferenceExpression) qualifierExpression;
       final PsiElement element = referenceExpression.resolve();
       if (!(element instanceof PsiVariable)) {
         return false;
       }
       final PsiVariable variable = (PsiVariable) element;
       if (!IteratorUtils.containsCallToScannerNext(context, variable, true)) {
         notUpdated.add(qualifierExpression);
         return true;
       }
     } else {
       if (!IteratorUtils.containsCallToScannerNext(context, null, true)) {
         notUpdated.add(methodCallExpression);
         return true;
       }
     }
   }
   return false;
 }
 private static boolean isInConcatenationContext(PsiElement element) {
   final PsiElement parent = element.getParent();
   if (parent instanceof PsiPolyadicExpression) {
     final PsiPolyadicExpression parentExpression = (PsiPolyadicExpression) parent;
     final PsiType parentType = parentExpression.getType();
     if (parentType == null) {
       return false;
     }
     final String parentTypeText = parentType.getCanonicalText();
     return JAVA_LANG_STRING.equals(parentTypeText);
   } else if (parent instanceof PsiAssignmentExpression) {
     final PsiAssignmentExpression parentExpression = (PsiAssignmentExpression) parent;
     final IElementType tokenType = parentExpression.getOperationTokenType();
     if (!JavaTokenType.PLUSEQ.equals(tokenType)) {
       return false;
     }
     final PsiType parentType = parentExpression.getType();
     if (parentType == null) {
       return false;
     }
     final String parentTypeText = parentType.getCanonicalText();
     return JAVA_LANG_STRING.equals(parentTypeText);
   } else if (parent instanceof PsiExpressionList) {
     final PsiElement grandParent = parent.getParent();
     if (!(grandParent instanceof PsiMethodCallExpression)) {
       return false;
     }
     final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) grandParent;
     final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
     final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
     final PsiType type;
     if (qualifierExpression == null) {
       // to use the intention inside the source of
       // String and StringBuffer
       type = methodExpression.getType();
     } else {
       type = qualifierExpression.getType();
     }
     if (type == null) {
       return false;
     }
     final String className = type.getCanonicalText();
     if (CommonClassNames.JAVA_LANG_STRING_BUFFER.equals(className)
         || CommonClassNames.JAVA_LANG_STRING_BUILDER.equals(className)) {
       @NonNls final String methodName = methodExpression.getReferenceName();
       if (!"append".equals(methodName) && !"insert".equals(methodName)) {
         return false;
       }
       final PsiElement method = methodExpression.resolve();
       return method != null;
     } else if (JAVA_LANG_STRING.equals(className)) {
       @NonNls final String methodName = methodExpression.getReferenceName();
       if (!"indexOf".equals(methodName)
           && !"lastIndexOf".equals(methodName)
           && !"replace".equals(methodName)) {
         return false;
       }
       final PsiElement method = methodExpression.resolve();
       return method != null;
     }
   }
   return false;
 }
 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;
 }
 private static void removeParensFromPolyadicExpression(
     @NotNull PsiPolyadicExpression polyadicExpression, boolean ignoreClarifyingParentheses) {
   for (PsiExpression operand : polyadicExpression.getOperands()) {
     removeParentheses(operand, 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);
     }
   }
 }