List<PsiElement> (@NotNull PsiElement parent, int startOffset, int endOffset) { int estimatedElements = parent.getTextLength()/2; List<PsiElement> result = new ArrayList<>(estimatedElements); int offset = parent.getTextRange().getStartOffset(); IntStack starts = new IntArrayList(STARTING_TREE_HEIGHT); Stack<PsiElement> elements = new Stack<>(STARTING_TREE_HEIGHT); Stack<PsiElement> children = new Stack<>(STARTING_TREE_HEIGHT); PsiElement element = parent; PsiElement child = PsiUtilCore.NULL_PSI_ELEMENT; List<Condition<PsiElement>> filters = EP_NAME.getExtensionList(); while (true) { ProgressIndicatorProvider.checkCanceled(); for (Condition<PsiElement> filter : filters) { if (!filter.value(element)) { assert child == PsiUtilCore.NULL_PSI_ELEMENT; child = null; // do not want to process children break; } } boolean startChildrenVisiting; if (child == PsiUtilCore.NULL_PSI_ELEMENT) { startChildrenVisiting = true; child = element.getFirstChild(); } else { startChildrenVisiting = false; } if (child == null) { if (startChildrenVisiting) { // leaf element offset += element.getTextLength(); } if (elements.isEmpty()) break; int start = starts.popInt(); if (startOffset <= start && offset <= endOffset) { assert element != null; assert element != PsiUtilCore.NULL_PSI_ELEMENT; result.add(element); } element = elements.pop(); child = children.pop(); } else { // composite element if (offset > endOffset) break; children.push(child.getNextSibling()); starts.push(offset); assert element != null; assert element != PsiUtilCore.NULL_PSI_ELEMENT; elements.push(element); element = child; child = PsiUtilCore.NULL_PSI_ELEMENT; } } return result; }