/** * Tries to find node that is direct or indirect previous node of the given node. * * <p>E.g. there is a possible use-case: * * <pre> * n1 * / \ * n21 n22 * | | * n31 n32 * </pre> * * Let's assume that target node is <code>'n32'</code>. 'n31' is assumed to be returned from this * method then. * * <p><b>Note:</b> current method avoids going too deep if found node type is the same as start * node type * * @return direct or indirect previous node of the given one having target type if possible; * <code>null</code> otherwise */ private static boolean findPreviousNode( AlignmentInColumnsConfig config, ASTNode from, IElementType targetType, boolean processFrom, boolean processParent, NodeProcessor processor) { if (from == null) return false; for (ASTNode prev = processFrom ? from : from.getTreePrev(); prev != null; prev = prev.getTreePrev()) { IElementType prevType = prev.getElementType(); if (prevType == targetType) { if (processor.targetTypeFound(prev)) return true; } else if (config.getWhiteSpaceTokenTypes().contains(prevType)) { if (processor.whitespaceFound(prev)) return true; } if (findPreviousNode(config, prev.getLastChildNode(), targetType, true, false, processor)) return true; } if (processParent) { for (ASTNode parent = from.getTreeParent(); parent != null; parent = parent.getTreeParent()) { if (findPreviousNode(config, parent, targetType, false, false, processor)) return true; } } return false; }