Result (@NotNull Context context) { IndentData indent = calculateAlignmentAnchorIndent(context); if (indent == null) { return Result.TARGET_BLOCK_PROCESSED_NOT_ALIGNED; } WhiteSpace whiteSpace = context.targetBlock().getWhiteSpace(); if (whiteSpace.containsLineFeeds() && applyIndentToTheFirstBlockOnLine(indent, context)) { return Result.TARGET_BLOCK_ALIGNED; } int diff = getAlignmentIndentDiff(indent, context); if (diff == 0) { return Result.TARGET_BLOCK_ALIGNED; } if (diff > 0) { int alignmentSpaces = whiteSpace.getSpaces() + diff; whiteSpace.setSpaces(alignmentSpaces, whiteSpace.getIndentSpaces()); if (!whiteSpace.containsLineFeeds()) { // Avoid tabulations usage for aligning blocks that are not the first blocks on a line. whiteSpace.setForceSkipTabulationsUsage(true); } return Result.TARGET_BLOCK_ALIGNED; } if (!context.alignment().isAllowBackwardShift()) { return Result.TARGET_BLOCK_PROCESSED_NOT_ALIGNED; } LeafBlockWrapper offsetResponsibleBlock = context.alignment().getOffsetRespBlockBefore(context.targetBlock()); if (offsetResponsibleBlock == null) { return Result.TARGET_BLOCK_PROCESSED_NOT_ALIGNED; } if (offsetResponsibleBlock.getWhiteSpace().isIsReadOnly()) { // We're unable to perform backward shift because white space for the target element is read-only. return Result.UNABLE_TO_ALIGN_BACKWARD_BLOCK; } if (!CoreFormatterUtil.allowBackwardAlignment(offsetResponsibleBlock, context.targetBlock(), context.alignmentMappings())) { return Result.UNABLE_TO_ALIGN_BACKWARD_BLOCK; } // There is a possible case that alignment options are defined incorrectly. Consider the following example: // int i1; // int i2, i3; // There is a problem if all blocks above use the same alignment - block 'i1' is shifted to right in order to align // to block 'i3' and reformatting starts back after 'i1'. Now 'i2' is shifted to left as well in order to align to the // new 'i1' position. That changes 'i3' position as well that causes 'i1' to be shifted right one more time. // Hence, we have endless cycle here. We remember information about blocks that caused indentation change because of // alignment of blocks located before them and skip alignment every time we detect an endless cycle. Set<LeafBlockWrapper> blocksCausedRealignment = context.backwardShiftedAlignedBlocks().get(offsetResponsibleBlock); if (blocksCausedRealignment != null && blocksCausedRealignment.contains(context.targetBlock())) { return Result.RECURSION_DETECTED; } WhiteSpace previousWhiteSpace = offsetResponsibleBlock.getWhiteSpace(); previousWhiteSpace.setSpaces(previousWhiteSpace.getSpaces() - diff, previousWhiteSpace.getIndentOffset()); // Avoid tabulations usage for aligning blocks that are not the first blocks on a line. if (!previousWhiteSpace.containsLineFeeds()) { previousWhiteSpace.setForceSkipTabulationsUsage(true); } return Result.BACKWARD_BLOCK_ALIGNED; }