void (@NotNull PsiFile root, long restrictRange, long priorityRange, @NotNull List<PsiElement> inside, @NotNull LongList insideRanges, @NotNull List<PsiElement> outside, @NotNull LongList outsideRanges, @NotNull List<? super PsiElement> outParents, @NotNull LongList outParentRanges) { int startOffset = TextRangeScalarUtil.startOffset(restrictRange); int endOffset = TextRangeScalarUtil.endOffset(restrictRange); List<Condition<PsiElement>> filters = CollectHighlightsUtil.EP_NAME.getExtensionList(); IntStack starts = new IntArrayList(STARTING_TREE_HEIGHT); starts.push(startOffset); Stack<PsiElement> elements = new Stack<>(STARTING_TREE_HEIGHT); Stack<PsiElement> children = new Stack<>(STARTING_TREE_HEIGHT); PsiElement element = root; PsiElement child = HAVE_TO_GET_CHILDREN; int offset = 0; while (true) { ProgressManager.checkCanceled(); for (Condition<PsiElement> filter : filters) { if (!filter.value(element)) { assert child == HAVE_TO_GET_CHILDREN; child = null; // do not want to process children break; } } boolean startChildrenVisiting; if (child == HAVE_TO_GET_CHILDREN) { startChildrenVisiting = true; child = element.getFirstChild(); } else { startChildrenVisiting = false; } if (child == null) { if (startChildrenVisiting) { // leaf element offset += element.getTextLength(); } int start = starts.popInt(); if (startOffset <= start && offset <= endOffset) { if (TextRangeScalarUtil.containsRange(priorityRange, start, offset)) { inside.add(element); insideRanges.add(TextRangeScalarUtil.toScalarRange(start, offset)); } else { outside.add(element); outsideRanges.add(TextRangeScalarUtil.toScalarRange(start, offset)); } } if (elements.isEmpty()) break; element = elements.pop(); child = children.pop(); } else { // composite element if (offset > endOffset) break; children.push(child.getNextSibling()); starts.push(offset); elements.push(element); element = child; child = HAVE_TO_GET_CHILDREN; } } PsiElement parent = !outside.isEmpty() ? outside.get(outside.size() - 1) : !inside.isEmpty() ? inside.get(inside.size() - 1) : CollectHighlightsUtil.findCommonParent(root, startOffset, endOffset); while (parent != null && !(parent instanceof PsiFile)) { parent = parent.getParent(); if (parent != null) { outParents.add(parent); TextRange textRange = parent.getTextRange(); assert textRange != null : "Text range for " + parent + " is null. " + parent.getClass() +"; root: "+root+": "+root.getVirtualFile(); outParentRanges.add(TextRangeScalarUtil.toScalarRange(textRange)); } } assert inside.size() == insideRanges.size(); assert outside.size() == outsideRanges.size(); assert outParents.size() == outParentRanges.size(); }