void (@NotNull PsiPolyadicExpression polyadicExpression) { final PsiExpression[] operands = polyadicExpression.getOperands(); if (operands.length < 2) { expectedType = null; return; } for (PsiExpression operand : operands) { if (operand == null || operand.getType() == null) { expectedType = null; return; } } final IElementType tokenType = polyadicExpression.getOperationTokenType(); final PsiType type = polyadicExpression.getType(); final PsiType wrappedExpressionType = wrappedExpression.getType(); if (TypeUtils.isJavaLangString(type) || isArithmeticOperation(tokenType) || isBooleanOperation(tokenType)) { expectedType = type; } else if (isShiftOperation(tokenType)) { expectedType = TypeUtils.unaryNumericPromotion(wrappedExpressionType); } else if (ComparisonUtils.isEqualityComparison(polyadicExpression)) { final PsiExpression operand1 = operands[0]; final PsiExpression operand2 = operands[1]; if (operand1 == wrappedExpression || operand2 == wrappedExpression) { final PsiType type1 = operand1.getType(); final PsiType type2 = operand2.getType(); if (type1 instanceof PsiPrimitiveType) { expectedType = expectedPrimitiveType((PsiPrimitiveType)type1, type2); } else if (type2 instanceof PsiPrimitiveType) { expectedType = expectedPrimitiveType((PsiPrimitiveType)type2, type1); } else { expectedType = TypeUtils.getObjectType(wrappedExpression); } } else { // third or more operand must always be boolean or does not compile expectedType = TypeConversionUtil.isBooleanType(wrappedExpressionType) ? PsiTypes.booleanType() : null; } } else if (ComparisonUtils.isComparisonOperation(tokenType)) { if (operands.length != 2) { expectedType = null; return; } else if (!TypeConversionUtil.isPrimitiveAndNotNull(wrappedExpressionType)) { if (PsiPrimitiveType.getUnboxedType(wrappedExpressionType) == null) { return; } } expectedType = TypeConversionUtil.binaryNumericPromotion(operands[0].getType(), operands[1].getType()); } else { expectedType = null; } }