void (PsiExpression expression, PsiPolyadicExpression polyadicExpression, boolean seenString) { PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression); if (parent == null) { return; } //might be null if expression is the first operand @Nullable PsiElement previousPlus = expression.getPrevSibling(); while (previousPlus != null && !(previousPlus instanceof PsiJavaToken javaToken && javaToken.getTokenType() == JavaTokenType.PLUS)) { previousPlus = previousPlus.getPrevSibling(); } PsiElement nextPlus = expression.getNextSibling(); while (nextPlus != null && !(nextPlus instanceof PsiJavaToken javaToken && javaToken.getTokenType() == JavaTokenType.PLUS)) { nextPlus = nextPlus.getNextSibling(); } if (nextPlus == null) { return; } int position = 0; PsiExpression[] operands = polyadicExpression.getOperands(); for (int i = 0; i < operands.length; i++) { if (operands[i] == expression) { position = i; } } if (position >= operands.length - 1) { return; } PsiExpression nextExpression = operands[position + 1]; StringBuilder builder = new StringBuilder(); boolean isFirstOperand = operands[0] == expression; boolean meetPreviousPlus = isFirstOperand; boolean meetNextPlus = false; boolean meetNextOperand = false; CommentTracker generalTracker = new CommentTracker(); CommentTracker firstTracker = new CommentTracker(); //base case: ..expr_+_""_+_expr.. for (PsiElement child : polyadicExpression.getChildren()) { if (!meetPreviousPlus) { // .<here>.expr_+_""_+_expr.. if (previousPlus != child) { builder.append(child.getText()); generalTracker.markUnchanged(child); } else { // ..expr_+<here>_""_+_expr.. meetPreviousPlus = true; builder.append(child.getText()); } } else if (!meetNextPlus) { //skip elements between pluses if (nextPlus == child) { // ..expr_+_""_+<here>_expr.. meetNextPlus = true; } } else if (!meetNextOperand) { if (nextExpression != child) { if (isFirstOperand) { // ""_+_<here>expr - it is impossible to build expression with comments in the beginning firstTracker.grabComments(child); generalTracker.markUnchanged(child); } else { // ..expr_+_""_+_<here>expr.. builder.append(child.getText()); generalTracker.markUnchanged(child); } } else { // ..expr_+_""_+_expr<here>.. builder.append(buildReplacement(nextExpression, seenString, generalTracker)); meetNextOperand = true; } } else { // ..expr_+_""_+_expr<here>..<here> builder.append(child.getText()); generalTracker.markUnchanged(child); } } final PsiElement replacementExpression = CodeStyleManager.getInstance(polyadicExpression.getProject()).performActionWithFormatterDisabled(new Computable<>() { @Override public PsiElement compute() { return generalTracker.replaceAndRestoreComments(polyadicExpression, builder.toString().trim()); } }); if (replacementExpression instanceof PsiPolyadicExpression psiPolyadicExpression) { PsiExpression[] expressionOperands = psiPolyadicExpression.getOperands(); if (expressionOperands.length - 1 < position) { return; } firstTracker.insertCommentsBefore(replacementExpression); } }