diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerWindowPresenter.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerWindowPresenter.java index 828825c9a1..fcaa91ab00 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerWindowPresenter.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerWindowPresenter.java @@ -128,6 +128,7 @@ public class DesignerWindowPresenter { private void initialiseNodeInfoSection() { view.getMetricResultsListView().setCellFactory(param -> new MetricResultListCell()); + view.getScopeHierarchyTreeView().setCellFactory(param -> new ScopeHierarchyTreeCell()); } @@ -188,6 +189,8 @@ public class DesignerWindowPresenter { .filter(result -> !result.isNaN()) .count()); + TreeItem rootScope = ScopeHierarchyTreeItem.buildAscendantHerarchy(selectedValue); + view.getScopeHierarchyTreeView().setRoot(rootScope); DesignerUtil.highlightNode(view.getCodeEditorArea(), selectedValue); } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/ScopeHierarchyTreeCell.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/ScopeHierarchyTreeCell.java new file mode 100644 index 0000000000..5fb88adee0 --- /dev/null +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/ScopeHierarchyTreeCell.java @@ -0,0 +1,46 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner; + +import net.sourceforge.pmd.lang.java.ast.TypeNode; +import net.sourceforge.pmd.lang.symboltable.NameDeclaration; +import net.sourceforge.pmd.lang.symboltable.Scope; + +import javafx.scene.control.TreeCell; + +/** + * @author Clément Fournier + * @since 6.0.0 + */ +public class ScopeHierarchyTreeCell extends TreeCell { + + @Override + protected void updateItem(Object item, boolean empty) { + super.updateItem(item, empty); + + if (empty || item == null) { + setText(null); + setGraphic(null); + } else { + setText(item instanceof Scope ? getTextForScope((Scope) item) + : getTextForDeclaration((NameDeclaration) item)); + } + } + + + private String getTextForScope(Scope scope) { + return scope.getClass().getSimpleName(); + } + + + private String getTextForDeclaration(NameDeclaration declaration) { + + Class type = declaration.getNode() instanceof TypeNode ? ((TypeNode) declaration.getNode()).getType() + : null; + + return declaration.getName() + (type != null ? " : " + type.getSimpleName() : ""); + } + +} diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/ScopeHierarchyTreeItem.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/ScopeHierarchyTreeItem.java new file mode 100644 index 0000000000..9223ace23c --- /dev/null +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/ScopeHierarchyTreeItem.java @@ -0,0 +1,79 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner; + +import java.util.List; +import java.util.Map.Entry; + +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.symboltable.NameDeclaration; +import net.sourceforge.pmd.lang.symboltable.NameOccurrence; +import net.sourceforge.pmd.lang.symboltable.Scope; +import net.sourceforge.pmd.lang.symboltable.ScopedNode; + +import javafx.scene.control.TreeItem; + +/** + * @author Clément Fournier + * @since 6.0.0 + */ +public class ScopeHierarchyTreeItem extends TreeItem { + + private ScopeHierarchyTreeItem(Object scopeOrDecl) { + super(scopeOrDecl); + setExpanded(true); + } + + + /** + * Gets the scope hierarchy of a node. + * + * @param node Node + * + * @return Root of the tree + */ + public static ScopeHierarchyTreeItem buildAscendantHerarchy(Node node) { + ScopeHierarchyTreeItem item = buildAscendantHierarchyHelper(getScope(node)); + while (item.getParent() != null) { + item = (ScopeHierarchyTreeItem) item.getParent(); + } + + return item; + + } + + + private static ScopeHierarchyTreeItem buildAscendantHierarchyHelper(Scope scope) { + if (scope == null) { + return null; + } + + ScopeHierarchyTreeItem scopeTreeNode = new ScopeHierarchyTreeItem(scope); + + for (Entry> entry : scope.getDeclarations().entrySet()) { + ScopeHierarchyTreeItem nameDeclaration = new ScopeHierarchyTreeItem(entry.getKey()); + scopeTreeNode.getChildren().add(nameDeclaration); + } + + ScopeHierarchyTreeItem parent = buildAscendantHierarchyHelper(scope.getParent()); + + if (parent == null) { + return scopeTreeNode; + } else { + parent.getChildren().add(scopeTreeNode); + return scopeTreeNode; + } + } + + + private static Scope getScope(Node node) { + if (node instanceof ScopedNode) { + return ((ScopedNode) node).getScope(); + } + return null; + } + + +} diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/view/DesignerWindow.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/view/DesignerWindow.java index 81afd1f28e..dc6291d223 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/view/DesignerWindow.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/view/DesignerWindow.java @@ -49,6 +49,8 @@ public class DesignerWindow implements Initializable { @FXML public MenuItem licenseMenuItem; @FXML + public TreeView scopeHierarchyTreeView; + @FXML private CodeArea codeEditorArea; @FXML private Menu languageMenu; @@ -162,6 +164,11 @@ public class DesignerWindow implements Initializable { } + public TreeView getScopeHierarchyTreeView() { + return scopeHierarchyTreeView; + } + + public CodeArea getCodeEditorArea() { return codeEditorArea; } @@ -217,11 +224,6 @@ public class DesignerWindow implements Initializable { } - public TitledPane getAstTitledPane() { - return astTitledPane; - } - - public TitledPane getXpathEditorTitledPane() { return xpathEditorTitledPane; } diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/designer.css b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/designer.css index 72ec25b622..e8dfc52fcb 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/designer.css +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/designer.css @@ -4,8 +4,6 @@ -fx-font-size: 11pt; } - - .titled-pane > .title { -fx-pref-height: 28.0; } @@ -16,7 +14,6 @@ -fx-background-color: derive(-fx-base, -10%); } - .styled-text-area { -fx-border-color: -fx-outer-border, -fx-text-box-border; -fx-border-insets: -4 -4 -6 -5, -2 -2 -5 -3; diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml index b9ffcb2784..b30fa797a9 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml @@ -16,6 +16,8 @@ + + @@ -42,7 +44,7 @@ - + @@ -69,7 +71,15 @@ - + + + + + + + + + @@ -112,13 +122,13 @@ - - - - - - - + + + + + + +