Search in sources :

Example 1 with TIntStack

use of gnu.trove.TIntStack in project intellij-community by JetBrains.

the class Divider method divideInsideAndOutsideInOneRoot.

private static void divideInsideAndOutsideInOneRoot(@NotNull PsiFile root, @NotNull TextRange restrictRange, @NotNull TextRange priorityRange, @NotNull List<PsiElement> inside, @NotNull List<ProperTextRange> insideRanges, @NotNull List<PsiElement> outside, @NotNull List<ProperTextRange> outsideRanges, @NotNull List<PsiElement> outParents, @NotNull List<ProperTextRange> outParentRanges, boolean includeParents) {
    int startOffset = restrictRange.getStartOffset();
    int endOffset = restrictRange.getEndOffset();
    final Condition<PsiElement>[] filters = Extensions.getExtensions(CollectHighlightsUtil.EP_NAME);
    final TIntStack starts = new TIntStack(STARTING_TREE_HEIGHT);
    starts.push(startOffset);
    final Stack<PsiElement> elements = new Stack<>(STARTING_TREE_HEIGHT);
    final 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;
                // do not want to process children
                child = null;
                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.pop();
            if (startOffset <= start && offset <= endOffset) {
                if (priorityRange.containsRange(start, offset)) {
                    inside.add(element);
                    insideRanges.add(new ProperTextRange(start, offset));
                } else {
                    outside.add(element);
                    outsideRanges.add(new ProperTextRange(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;
        }
    }
    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 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(ProperTextRange.create(textRange));
            }
        }
    }
    assert inside.size() == insideRanges.size();
    assert outside.size() == outsideRanges.size();
    assert outParents.size() == outParentRanges.size();
}
Also used : Condition(com.intellij.openapi.util.Condition) ProperTextRange(com.intellij.openapi.util.ProperTextRange) PsiFile(com.intellij.psi.PsiFile) ProperTextRange(com.intellij.openapi.util.ProperTextRange) TextRange(com.intellij.openapi.util.TextRange) TIntStack(gnu.trove.TIntStack) PsiElement(com.intellij.psi.PsiElement) TIntStack(gnu.trove.TIntStack) Stack(com.intellij.util.containers.Stack)

Example 2 with TIntStack

use of gnu.trove.TIntStack in project intellij-community by JetBrains.

the class PsiUtil method iterateSupers.

public static Iterable<PsiClass> iterateSupers(@NotNull final PsiClass psiClass, final boolean includeSelf) {
    return new Iterable<PsiClass>() {

        @Override
        public Iterator<PsiClass> iterator() {
            return new Iterator<PsiClass>() {

                TIntStack indices = new TIntStack();

                Stack<PsiClassType[]> superTypesStack = new Stack<>();

                PsiClass current;

                boolean nextObtained;

                Set<PsiClass> visited = new HashSet<>();

                {
                    if (includeSelf) {
                        current = psiClass;
                        nextObtained = true;
                    } else {
                        current = null;
                        nextObtained = false;
                    }
                    pushSuper(psiClass);
                }

                @Override
                public boolean hasNext() {
                    nextElement();
                    return current != null;
                }

                private void nextElement() {
                    if (nextObtained)
                        return;
                    nextObtained = true;
                    while (!superTypesStack.empty()) {
                        assert indices.size() > 0;
                        int i = indices.pop();
                        PsiClassType[] superTypes = superTypesStack.peek();
                        while (i < superTypes.length) {
                            PsiClass clazz = superTypes[i].resolve();
                            if (clazz != null && !visited.contains(clazz)) {
                                current = clazz;
                                visited.add(clazz);
                                indices.push(i + 1);
                                pushSuper(clazz);
                                return;
                            }
                            i++;
                        }
                        superTypesStack.pop();
                    }
                    current = null;
                }

                private void pushSuper(PsiClass clazz) {
                    superTypesStack.push(clazz.getSuperTypes());
                    indices.push(0);
                }

                @Override
                @NotNull
                public PsiClass next() {
                    nextElement();
                    nextObtained = false;
                    if (current == null)
                        throw new NoSuchElementException();
                    return current;
                }

                @Override
                public void remove() {
                    throw new IllegalStateException("should not be called");
                }
            };
        }
    };
}
Also used : HashSet(com.intellij.util.containers.HashSet) TokenSet(com.intellij.psi.tree.TokenSet) TIntStack(gnu.trove.TIntStack) TIntStack(gnu.trove.TIntStack)

Example 3 with TIntStack

use of gnu.trove.TIntStack in project intellij-community by JetBrains.

the class LightStubBuilder method buildStubTree.

protected void buildStubTree(@NotNull LighterAST tree, @NotNull LighterASTNode root, @NotNull StubElement rootStub) {
    final Stack<LighterASTNode> parents = new Stack<>();
    final TIntStack childNumbers = new TIntStack();
    final BooleanStack parentsStubbed = new BooleanStack();
    final Stack<List<LighterASTNode>> kinderGarden = new Stack<>();
    final Stack<StubElement> parentStubs = new Stack<>();
    LighterASTNode parent = null;
    LighterASTNode element = root;
    List<LighterASTNode> children = null;
    int childNumber = 0;
    StubElement parentStub = rootStub;
    boolean immediateParentStubbed = true;
    nextElement: while (element != null) {
        final StubElement stub = createStub(tree, element, parentStub);
        boolean hasStub = stub != parentStub || parent == null;
        if (hasStub && !immediateParentStubbed) {
            ((ObjectStubBase) stub).markDangling();
        }
        if (parent == null || !skipNode(tree, parent, element)) {
            final List<LighterASTNode> kids = tree.getChildren(element);
            if (!kids.isEmpty()) {
                if (parent != null) {
                    parents.push(parent);
                    childNumbers.push(childNumber);
                    kinderGarden.push(children);
                    parentStubs.push(parentStub);
                    parentsStubbed.push(immediateParentStubbed);
                }
                parent = element;
                immediateParentStubbed = hasStub;
                element = (children = kids).get(childNumber = 0);
                parentStub = stub;
                if (!skipNode(tree, parent, element))
                    continue nextElement;
            }
        }
        while (children != null && ++childNumber < children.size()) {
            element = children.get(childNumber);
            if (!skipNode(tree, parent, element))
                continue nextElement;
        }
        element = null;
        while (!parents.isEmpty()) {
            parent = parents.pop();
            childNumber = childNumbers.pop();
            children = kinderGarden.pop();
            parentStub = parentStubs.pop();
            immediateParentStubbed = parentsStubbed.pop();
            while (++childNumber < children.size()) {
                element = children.get(childNumber);
                if (!skipNode(tree, parent, element))
                    continue nextElement;
            }
            element = null;
        }
    }
}
Also used : List(java.util.List) TIntStack(gnu.trove.TIntStack) BooleanStack(com.intellij.util.containers.BooleanStack) TIntStack(gnu.trove.TIntStack) BooleanStack(com.intellij.util.containers.BooleanStack) Stack(com.intellij.util.containers.Stack)

Example 4 with TIntStack

use of gnu.trove.TIntStack in project intellij-community by JetBrains.

the class CollectHighlightsUtil method getElementsToHighlight.

@NotNull
private static List<PsiElement> getElementsToHighlight(@NotNull PsiElement parent, final int startOffset, final int endOffset) {
    final List<PsiElement> result = new ArrayList<>();
    final int currentOffset = parent.getTextRange().getStartOffset();
    final Condition<PsiElement>[] filters = Extensions.getExtensions(EP_NAME);
    int offset = currentOffset;
    final TIntStack starts = new TIntStack(STARTING_TREE_HEIGHT);
    final Stack<PsiElement> elements = new Stack<>(STARTING_TREE_HEIGHT);
    final Stack<PsiElement> children = new Stack<>(STARTING_TREE_HEIGHT);
    PsiElement element = parent;
    PsiElement child = PsiUtilCore.NULL_PSI_ELEMENT;
    while (true) {
        ProgressIndicatorProvider.checkCanceled();
        for (Condition<PsiElement> filter : filters) {
            if (!filter.value(element)) {
                assert child == PsiUtilCore.NULL_PSI_ELEMENT;
                // do not want to process children
                child = null;
                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.pop();
            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;
}
Also used : Condition(com.intellij.openapi.util.Condition) ArrayList(java.util.ArrayList) TIntStack(gnu.trove.TIntStack) PsiElement(com.intellij.psi.PsiElement) TIntStack(gnu.trove.TIntStack) Stack(com.intellij.util.containers.Stack) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

TIntStack (gnu.trove.TIntStack)4 Stack (com.intellij.util.containers.Stack)3 Condition (com.intellij.openapi.util.Condition)2 PsiElement (com.intellij.psi.PsiElement)2 ProperTextRange (com.intellij.openapi.util.ProperTextRange)1 TextRange (com.intellij.openapi.util.TextRange)1 PsiFile (com.intellij.psi.PsiFile)1 TokenSet (com.intellij.psi.tree.TokenSet)1 BooleanStack (com.intellij.util.containers.BooleanStack)1 HashSet (com.intellij.util.containers.HashSet)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 NotNull (org.jetbrains.annotations.NotNull)1