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();
}
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");
}
};
}
};
}
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;
}
}
}
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;
}
Aggregations