private void runHighlightVisitorsForInjected( @NotNull PsiFile injectedPsi, @NotNull final HighlightInfoHolder holder, @NotNull final ProgressIndicator progress) { HighlightVisitor[] filtered = getHighlightVisitors(injectedPsi); try { final List<PsiElement> elements = CollectHighlightsUtil.getElementsInRange(injectedPsi, 0, injectedPsi.getTextLength()); for (final HighlightVisitor visitor : filtered) { visitor.analyze( injectedPsi, true, holder, new Runnable() { @Override public void run() { for (PsiElement element : elements) { progress.checkCanceled(); visitor.visit(element); } } }); } } finally { incVisitorUsageCount(-1); } }
private static void divideInsideAndOutside( @NotNull PsiFile root, int startOffset, int endOffset, @NotNull TextRange range, @NotNull List<PsiElement> inside, @NotNull List<PsiElement> outside, boolean includeParents) { final int currentOffset = root.getTextRange().getStartOffset(); final Condition<PsiElement>[] filters = Extensions.getExtensions(CollectHighlightsUtil.EP_NAME); int offset = currentOffset; final TIntStack starts = new TIntStack(STARTING_TREE_HEIGHT); starts.push(startOffset); final Stack<PsiElement> elements = new Stack<PsiElement>(STARTING_TREE_HEIGHT); final Stack<PsiElement> children = new Stack<PsiElement>(STARTING_TREE_HEIGHT); PsiElement element = root; PsiElement child = PsiUtilBase.NULL_PSI_ELEMENT; while (true) { ProgressManager.checkCanceled(); for (Condition<PsiElement> filter : filters) { if (!filter.value(element)) { assert child == PsiUtilBase.NULL_PSI_ELEMENT; child = null; // do not want to process children break; } } boolean startChildrenVisiting; if (child == PsiUtilBase.NULL_PSI_ELEMENT) { startChildrenVisiting = true; child = element.getFirstChild(); } else { startChildrenVisiting = false; } if (child == null) { if (startChildrenVisiting) { // leaf element offset += element.getTextLength(); } int start = starts.pop(); if (startOffset <= start && offset <= endOffset) { if (range.containsRange(start, offset)) { inside.add(element); } else { outside.add(element); } } 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 = PsiUtilBase.NULL_PSI_ELEMENT; } } if (includeParents) { 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 != root) { parent = parent.getParent(); if (parent != null) outside.add(parent); } } }