String (@Nullable PsiExpression expression, int precedence, CommentTracker tracker) { if (expression == null) { return ""; } if (expression instanceof PsiMethodCallExpression) { String smartNegation = findSmartMethodNegation(expression); if (smartNegation != null) return smartNegation; } if (expression instanceof PsiParenthesizedExpression parenthesizedExpression) { PsiExpression operand = parenthesizedExpression.getExpression(); if (operand != null) { return '(' + getNegatedExpressionText(operand, tracker) + ')'; } } if (expression instanceof PsiAssignmentExpression && expression.getParent() instanceof PsiExpressionStatement) { String newOp = null; IElementType tokenType = ((PsiAssignmentExpression)expression).getOperationTokenType(); if (tokenType == JavaTokenType.ANDEQ) { newOp = "|="; } else if (tokenType == JavaTokenType.OREQ) { newOp = "&="; } if (newOp != null) { return tracker.text(((PsiAssignmentExpression)expression).getLExpression()) + newOp + getNegatedExpressionText(((PsiAssignmentExpression)expression).getRExpression()); } } if (expression instanceof PsiConditionalExpression conditionalExpression) { final boolean needParenthesis = ParenthesesUtils.getPrecedence(conditionalExpression) >= precedence; final String text = tracker.text(conditionalExpression.getCondition()) + '?' + getNegatedExpressionText(conditionalExpression.getThenExpression(), tracker) + ':' + getNegatedExpressionText(conditionalExpression.getElseExpression(), tracker); return needParenthesis ? "(" + text + ")" : text; } if (isNegation(expression)) { final PsiExpression negated = getNegated(expression); if (negated != null) { return ParenthesesUtils.getText(tracker.markUnchanged(negated), precedence); } } if (expression instanceof PsiPolyadicExpression polyadicExpression) { final IElementType tokenType = polyadicExpression.getOperationTokenType(); final PsiExpression[] operands = polyadicExpression.getOperands(); if (ComparisonUtils.isComparison(polyadicExpression)) { final String negatedComparison = ComparisonUtils.getNegatedComparison(tokenType); final StringBuilder result = new StringBuilder(); final boolean isEven = (operands.length & 1) != 1; for (int i = 0, length = operands.length; i < length; i++) { final PsiExpression operand = operands[i]; if (TypeUtils.hasFloatingPointType(operand) && !ComparisonUtils.isEqualityComparison(polyadicExpression)) { // preserve semantics for NaNs return "!(" + polyadicExpression.getText() + ')'; } if (i > 0) { if (isEven && (i & 1) != 1) { final PsiJavaToken token = polyadicExpression.getTokenBeforeOperand(operand); if (token != null) { result.append(token.getText()); } } else { result.append(negatedComparison); } } result.append(tracker.text(operand)); } return result.toString(); } if(tokenType.equals(JavaTokenType.ANDAND) || tokenType.equals(JavaTokenType.OROR)) { final String targetToken; final int newPrecedence; if (tokenType.equals(JavaTokenType.ANDAND)) { targetToken = "||"; newPrecedence = ParenthesesUtils.OR_PRECEDENCE; } else { targetToken = "&&"; newPrecedence = ParenthesesUtils.AND_PRECEDENCE; } final Function<PsiElement, String> replacer = child -> { if (child instanceof PsiExpression) { return getNegatedExpressionText((PsiExpression)child, newPrecedence, tracker); } return child instanceof PsiJavaToken ? targetToken : tracker.text(child); }; final String join = StringUtil.join(polyadicExpression.getChildren(), replacer, ""); return (newPrecedence > precedence) ? '(' + join + ')' : join; } } if (expression instanceof PsiLiteralExpression) { Object value = ((PsiLiteralExpression)expression).getValue(); if (value instanceof Boolean) { return String.valueOf(!((Boolean)value)); } } return '!' + ParenthesesUtils.getText(tracker.markUnchanged(expression), ParenthesesUtils.PREFIX_PRECEDENCE); }