| // 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()]); |
| } |
| } |