Scope hierarchy

This commit is contained in:
Clément Fournier
2017-09-16 20:26:58 +02:00
parent fee9c5cdef
commit 88f4e2722e
6 changed files with 154 additions and 17 deletions

View File

@ -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<Object> rootScope = ScopeHierarchyTreeItem.buildAscendantHerarchy(selectedValue);
view.getScopeHierarchyTreeView().setRoot(rootScope);
DesignerUtil.highlightNode(view.getCodeEditorArea(), selectedValue);
}

View File

@ -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<Object> {
@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() : "");
}
}

View File

@ -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<Object> {
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<NameDeclaration, List<NameOccurrence>> 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;
}
}

View File

@ -49,6 +49,8 @@ public class DesignerWindow implements Initializable {
@FXML
public MenuItem licenseMenuItem;
@FXML
public TreeView<Object> scopeHierarchyTreeView;
@FXML
private CodeArea codeEditorArea;
@FXML
private Menu languageMenu;
@ -162,6 +164,11 @@ public class DesignerWindow implements Initializable {
}
public TreeView<Object> 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;
}

View File

@ -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;

View File

@ -16,6 +16,8 @@
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.RadioMenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.control.ToolBar?>
@ -42,7 +44,7 @@
<Menu mnemonicParsing="false" text="About">
<items>
<MenuItem mnemonicParsing="false" text="About" />
<MenuItem fx:id="licenseMenuItem" mnemonicParsing="false" text="License" />
<MenuItem fx:id="licenseMenuItem" mnemonicParsing="false" text="License" />
</items>
</Menu>
</menus>
@ -69,7 +71,15 @@
</AnchorPane>
</content>
</TitledPane>
<TitledPane expanded="false" text="Scope hierarchy" />
<TitledPane animated="false" text="Scope hierarchy">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TreeView fx:id="scopeHierarchyTreeView" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</content>
</TitledPane>
<TitledPane fx:id="metricResultsTitledPane" expanded="false" prefHeight="200.0" prefWidth="200.0" text="Metrics">
<content>
<AnchorPane>
@ -112,13 +122,13 @@
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TitledPane fx:id="astTitledPane" collapsible="false" prefHeight="200.0" prefWidth="200.0" text="Abstract syntax tree" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<TreeView fx:id="astTreeView" prefHeight="200.0" prefWidth="200.0" />
</content>
</TitledPane>
</children>
<children>
<TitledPane fx:id="astTitledPane" collapsible="false" prefHeight="200.0" prefWidth="200.0" text="Abstract Syntax Tree" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<TreeView fx:id="astTreeView" prefHeight="200.0" prefWidth="200.0" />
</content>
</TitledPane>
</children>
</AnchorPane>
</items>
</SplitPane>