blob: 69a0a039f0e0cf5cfd113c94e38be3e95bd9205b [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package fuchsia.developer.plugin.fidl;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.SortableTreeElement;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import fuchsia.developer.plugin.fidl.psi.FidlNamedElement;
import fuchsia.developer.plugin.fidl.psi.FidlNamedElementImpl;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import org.jetbrains.annotations.NotNull;
public class FidlStructureViewElement implements StructureViewTreeElement, SortableTreeElement {
private NavigatablePsiElement element;
public FidlStructureViewElement(NavigatablePsiElement element) {
this.element = element;
}
@Override
public Object getValue() {
return element;
}
@Override
public void navigate(boolean requestFocus) {
element.navigate(requestFocus);
}
@Override
public boolean canNavigate() {
return element.canNavigate();
}
@Override
public boolean canNavigateToSource() {
return element.canNavigateToSource();
}
@NotNull
@Override
public String getAlphaSortKey() {
if (element instanceof FidlNamedElement) {
FidlNamedElement e = (FidlNamedElement) element;
return e.getIdentifierToken().getText();
}
String name = element.getName();
return name != null ? name : "";
}
@NotNull
@Override
public ItemPresentation getPresentation() {
ItemPresentation presentation = element.getPresentation();
if (presentation != null) {
return presentation;
}
PresentationData data = new PresentationData();
data.setPresentableText("here");
return data;
}
@Override
public TreeElement[] getChildren() {
// Children are the most proximate descendants that implement FidlNamedElementImpl
List<TreeElement> foundElements = new ArrayList<>();
Deque<NavigatablePsiElement> elementsToScan = new ArrayDeque<>();
List<NavigatablePsiElement> initialElements =
PsiTreeUtil.getChildrenOfTypeAsList(element, NavigatablePsiElement.class);
elementsToScan.addAll(initialElements);
while (!elementsToScan.isEmpty()) {
NavigatablePsiElement curr = elementsToScan.pop();
if (curr instanceof FidlNamedElementImpl) {
foundElements.add(new FidlStructureViewElement(curr));
} else {
NavigatablePsiElement[] currChildren =
PsiTreeUtil.getChildrenOfType(curr, NavigatablePsiElement.class);
if (currChildren == null) {
continue;
}
Collections.addAll(elementsToScan, currChildren);
}
}
return foundElements.toArray(new TreeElement[foundElements.size()]);
}
}