mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-808 Added Display as Graph action to the Datatype Manager
This commit is contained in:
parent
22675e9f39
commit
ae40102420
7 changed files with 523 additions and 3 deletions
|
@ -725,9 +725,16 @@
|
||||||
<P>For Typedefs, Pointers and Arrays, this action will navigate to the tree node of the
|
<P>For Typedefs, Pointers and Arrays, this action will navigate to the tree node of the
|
||||||
type to which respective refers.</P>
|
type to which respective refers.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<H3><A name="Type_Graph">Display Data Type as Graph</A></H3>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>For Structures, Unions and Pointers, will generate a graph of the type, with nodes
|
||||||
|
for each enclosed structure or pointed to type</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<P class="providedbyplugin">Provided by: <I>DataTypeManagerPlugin</I></P>
|
<P class="providedbyplugin">Provided by: <I>DataTypeManagerPlugin</I></P>
|
||||||
|
|
||||||
<P class="relatedtopic">Related Topics:</P>
|
<P class="relatedtopic">Related Topics:</P>
|
||||||
|
|
|
@ -191,6 +191,7 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
addLocalAction(new FindReferencesToFieldAction(plugin)); // DataType
|
addLocalAction(new FindReferencesToFieldAction(plugin)); // DataType
|
||||||
// addLocalAction( new FindDataTypesContainingAction(plugin) ); // DataType
|
// addLocalAction( new FindDataTypesContainingAction(plugin) ); // DataType
|
||||||
addLocalAction(new FindBaseDataTypeAction(plugin)); // DataType
|
addLocalAction(new FindBaseDataTypeAction(plugin)); // DataType
|
||||||
|
addLocalAction(new DisplayTypeAsGraphAction(plugin));
|
||||||
|
|
||||||
// toolbar actions
|
// toolbar actions
|
||||||
previousAction = new NextPreviousDataTypeAction(this, plugin.getName(), false);
|
previousAction = new NextPreviousDataTypeAction(this, plugin.getName(), false);
|
||||||
|
@ -344,8 +345,8 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
isToolbarAction = false;
|
isToolbarAction = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DataTypesActionContext(this, plugin.getProgram(), archiveGTree,
|
return new DataTypesActionContext(this, plugin.getProgram(), archiveGTree, clickedNode,
|
||||||
clickedNode, isToolbarAction);
|
isToolbarAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // overridden to handle special logic in plugin
|
@Override // overridden to handle special logic in plugin
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.plugin.core.datamgr.actions;
|
||||||
|
|
||||||
|
import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
|
import docking.ActionContext;
|
||||||
|
import docking.action.DockingAction;
|
||||||
|
import docking.action.MenuData;
|
||||||
|
import docking.widgets.tree.GTree;
|
||||||
|
import docking.widgets.tree.GTreeNode;
|
||||||
|
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||||
|
import ghidra.app.plugin.core.datamgr.DataTypesActionContext;
|
||||||
|
import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
||||||
|
import ghidra.app.services.GraphDisplayBroker;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.service.graph.GraphDisplayProvider;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import ghidra.util.task.TaskLauncher;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Action to display a Composite data type as a graph from the Data Type Manager
|
||||||
|
*
|
||||||
|
* The graphing is done recursively in a separate task
|
||||||
|
*/
|
||||||
|
public class DisplayTypeAsGraphAction extends DockingAction {
|
||||||
|
|
||||||
|
private DataTypeManagerPlugin plugin;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param plugin the plugin this action is contained in
|
||||||
|
*/
|
||||||
|
public DisplayTypeAsGraphAction(DataTypeManagerPlugin plugin) {
|
||||||
|
super("Display Data Type as Graph", plugin.getName());
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
String menuGroup = "ZVeryLast"; // it's own group; on the bottom
|
||||||
|
setPopupMenuData(new MenuData(new String[] { "Display as Graph" }, null, menuGroup));
|
||||||
|
setHelpLocation(new HelpLocation("DataTypeManagerPlugin", "Type_Graph"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext context) {
|
||||||
|
GraphDisplayBroker broker = plugin.getTool().getService(GraphDisplayBroker.class);
|
||||||
|
if (broker == null) {
|
||||||
|
Msg.showError(this, null, "Missing Plugin", "The Graph plugin is not installed.\n" +
|
||||||
|
"Please add the plugin implementing this service.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GraphDisplayProvider service = broker.getDefaultGraphDisplayProvider();
|
||||||
|
|
||||||
|
GTree gTree = (GTree) context.getContextObject();
|
||||||
|
TreePath[] selectionPaths = gTree.getSelectionPaths();
|
||||||
|
|
||||||
|
for (TreePath path : selectionPaths) {
|
||||||
|
GTreeNode node = (GTreeNode) path.getLastPathComponent();
|
||||||
|
if (!(node instanceof DataTypeNode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DataTypeNode dataTypeNode = (DataTypeNode) node;
|
||||||
|
DataType dt = dataTypeNode.getDataType();
|
||||||
|
if (dt instanceof TypeDef) {
|
||||||
|
dt = ((TypeDef) dt).getBaseDataType();
|
||||||
|
}
|
||||||
|
if (dt instanceof Composite || dt instanceof Pointer) {
|
||||||
|
TypeGraphTask task = new TypeGraphTask(dataTypeNode.getDataType(), service);
|
||||||
|
new TaskLauncher(task, plugin.getTool().getToolFrame());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
boolean enabled = false;
|
||||||
|
|
||||||
|
if (!(context instanceof DataTypesActionContext)) {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object contextObject = context.getContextObject();
|
||||||
|
GTree gtree = (GTree) contextObject;
|
||||||
|
TreePath[] selectionPaths = gtree.getSelectionPaths();
|
||||||
|
|
||||||
|
for (TreePath path : selectionPaths) {
|
||||||
|
|
||||||
|
GTreeNode node = (GTreeNode) path.getLastPathComponent();
|
||||||
|
if (!(node instanceof DataTypeNode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTypeNode dtNode = (DataTypeNode) node;
|
||||||
|
DataType dt = dtNode.getDataType();
|
||||||
|
if (dt instanceof TypeDef) {
|
||||||
|
dt = ((TypeDef) dt).getBaseDataType();
|
||||||
|
}
|
||||||
|
if (dt instanceof Composite || dt instanceof Pointer) {
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.plugin.core.datamgr.actions;
|
||||||
|
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.service.graph.*;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import ghidra.util.exception.CancelledException;
|
||||||
|
import ghidra.util.exception.GraphException;
|
||||||
|
import ghidra.util.task.Task;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Task to recursively graph and display a data type
|
||||||
|
*
|
||||||
|
* Nodes are generated for pointers and embedded structures
|
||||||
|
*/
|
||||||
|
public class TypeGraphTask extends Task {
|
||||||
|
|
||||||
|
private DataType type;
|
||||||
|
private String graphTitle;
|
||||||
|
private GraphDisplayProvider graphService;
|
||||||
|
|
||||||
|
public static final String TYPE_ATTRIBUTE = "Type";
|
||||||
|
public static final String EMBEDDED = "Composite";
|
||||||
|
public static final String POINTER = "Reference";
|
||||||
|
public static final String CONTENTS_ATTRIBUTE = "Contents";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param type the type to graph
|
||||||
|
* @param graphService the GraphService that will display the graph
|
||||||
|
*/
|
||||||
|
public TypeGraphTask(DataType type, GraphDisplayProvider graphService) {
|
||||||
|
super("Graph Data Type", true, false, true);
|
||||||
|
this.type = type;
|
||||||
|
if (this.type instanceof TypeDef) {
|
||||||
|
this.type = ((TypeDef) this.type).getBaseDataType();
|
||||||
|
}
|
||||||
|
this.graphTitle = "Graph of Type: " + type.getName();
|
||||||
|
this.graphService = graphService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(TaskMonitor monitor) throws CancelledException {
|
||||||
|
|
||||||
|
AttributedGraph graph = new AttributedGraph();
|
||||||
|
try {
|
||||||
|
if (type instanceof Pointer) {
|
||||||
|
recursePointer((Pointer) type, graph, null, monitor);
|
||||||
|
}
|
||||||
|
if (type instanceof Composite) {
|
||||||
|
recurseComposite((Composite) type, graph, null, null, monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CancelledException e) {
|
||||||
|
monitor.setMessage("Cancelling...");
|
||||||
|
graphTitle = graphTitle + " (partial)";
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphDisplay display;
|
||||||
|
try {
|
||||||
|
display = graphService.getGraphDisplay(false, monitor);
|
||||||
|
display.setGraph(graph, graphTitle, false, monitor);
|
||||||
|
}
|
||||||
|
catch (GraphException e) {
|
||||||
|
Msg.showError(this, null, "Data Type Graph Error",
|
||||||
|
"Unexpected error while graphing: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recurseComposite(Composite struct, AttributedGraph graph,
|
||||||
|
AttributedVertex lastVertex, String edgeType, TaskMonitor monitor)
|
||||||
|
throws CancelledException {
|
||||||
|
AttributedVertex newVertex = new AttributedVertex(struct.getName());
|
||||||
|
newVertex.setAttribute(CONTENTS_ATTRIBUTE, struct.toString());
|
||||||
|
if (lastVertex == null) {
|
||||||
|
graph.addVertex(newVertex);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AttributedEdge edge = graph.addEdge(lastVertex, newVertex);
|
||||||
|
if (edgeType == POINTER) {
|
||||||
|
edge.setAttribute("Color", "Blue");
|
||||||
|
}
|
||||||
|
edge.setAttribute(TYPE_ATTRIBUTE, edgeType);
|
||||||
|
if (edge.hasAttribute("Weight")) {
|
||||||
|
//did this already, don't cycle
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DataTypeComponent inner : struct.getComponents()) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
DataType dt = inner.getDataType();
|
||||||
|
if (dt instanceof TypeDef) {
|
||||||
|
dt = ((TypeDef) dt).getBaseDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dt instanceof Pointer) {
|
||||||
|
recursePointer((Pointer) dt, graph, newVertex, monitor);
|
||||||
|
}
|
||||||
|
else if (dt instanceof Composite) {
|
||||||
|
recurseComposite((Composite) dt, graph, newVertex, EMBEDDED, monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recursePointer(Pointer pointer, AttributedGraph graph, AttributedVertex lastVertex,
|
||||||
|
TaskMonitor monitor) throws CancelledException {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
DataType ptrType = pointer.getDataType();
|
||||||
|
if (ptrType == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ptrType instanceof TypeDef) {
|
||||||
|
ptrType = ((TypeDef) ptrType).getBaseDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptrType instanceof Pointer) {
|
||||||
|
recursePointer((Pointer) ptrType, graph, lastVertex, monitor);
|
||||||
|
}
|
||||||
|
else if (ptrType instanceof Composite) {
|
||||||
|
recurseComposite((Composite) ptrType, graph, lastVertex, POINTER, monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,251 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.plugin.core.datamgr.actions;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ghidra.graph.program.TestGraphDisplay;
|
||||||
|
import ghidra.graph.program.TestGraphService;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.service.graph.*;
|
||||||
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
|
import ghidra.util.exception.GraphException;
|
||||||
|
import ghidra.util.task.Task;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
public class TypeGraphTaskTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
|
private Structure base;
|
||||||
|
private Structure other;
|
||||||
|
private Pointer pointer;
|
||||||
|
private Pointer otherPointer;
|
||||||
|
private TypeDef otherTypeDef;
|
||||||
|
private TestGraphService graphService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
base = new StructureDataType("base structure", 16);
|
||||||
|
base.insert(0, new IntegerDataType());
|
||||||
|
|
||||||
|
other = new StructureDataType("another struct", 20);
|
||||||
|
other.insert(0, new IntegerDataType());
|
||||||
|
other.insert(1, new FloatDataType());
|
||||||
|
|
||||||
|
pointer = new PointerDataType(new IntegerDataType());
|
||||||
|
otherPointer = new PointerDataType(other);
|
||||||
|
|
||||||
|
otherTypeDef = new TypedefDataType("other_t", other);
|
||||||
|
|
||||||
|
graphService = new TestGraphService();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleStructure() throws GraphException {
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(1, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNestedStructure() throws GraphException {
|
||||||
|
base.insert(1, other);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
assertEquals(TypeGraphTask.EMBEDDED, e1.getAttribute(TypeGraphTask.TYPE_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStructureWithPointer() throws GraphException {
|
||||||
|
base.insert(1, pointer);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(1, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPointerToStructure() throws GraphException {
|
||||||
|
base.insert(1, otherPointer);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
assertEquals(TypeGraphTask.POINTER, e1.getAttribute(TypeGraphTask.TYPE_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmbeddedAndPointer() throws GraphException {
|
||||||
|
base.insert(1, other);
|
||||||
|
base.insert(2, pointer);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
assertEquals(TypeGraphTask.EMBEDDED, e1.getAttribute(TypeGraphTask.TYPE_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPointerToPointer() throws GraphException {
|
||||||
|
Pointer pointerToPointer = new PointerDataType(otherPointer);
|
||||||
|
base.insert(1, pointerToPointer);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
assertEquals(TypeGraphTask.POINTER, e1.getAttribute(TypeGraphTask.TYPE_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmbeddedTypedef() throws GraphException {
|
||||||
|
base.insert(1, otherTypeDef);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
assertEquals(TypeGraphTask.EMBEDDED, e1.getAttribute(TypeGraphTask.TYPE_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPointerToTypedef() throws GraphException {
|
||||||
|
Pointer typedefPtr = new PointerDataType(otherTypeDef);
|
||||||
|
base.insert(1, typedefPtr);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
assertEquals(TypeGraphTask.POINTER, e1.getAttribute(TypeGraphTask.TYPE_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPointerToSelf() throws GraphException {
|
||||||
|
Pointer selfPtr = new PointerDataType(base);
|
||||||
|
base.insert(1, selfPtr);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(1, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v1);
|
||||||
|
assertNotNull(e1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPointerCycle() throws GraphException {
|
||||||
|
base.insert(1, otherPointer);
|
||||||
|
Pointer basePtr = new PointerDataType(base);
|
||||||
|
other.insert(1, basePtr);
|
||||||
|
Task task = new TypeGraphTask(base, graphService);
|
||||||
|
task.monitoredRun(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
TestGraphDisplay display =
|
||||||
|
(TestGraphDisplay) graphService.getGraphDisplay(true, TaskMonitor.DUMMY);
|
||||||
|
AttributedGraph graph = display.getGraph();
|
||||||
|
|
||||||
|
assertEquals(2, graph.getVertexCount());
|
||||||
|
AttributedVertex v1 = graph.getVertex(base.getName());
|
||||||
|
assertNotNull(v1);
|
||||||
|
AttributedVertex v2 = graph.getVertex(other.getName());
|
||||||
|
assertNotNull(v2);
|
||||||
|
AttributedEdge e1 = graph.getEdge(v1, v2);
|
||||||
|
assertNotNull(e1);
|
||||||
|
AttributedEdge e2 = graph.getEdge(v2, v1);
|
||||||
|
assertNotNull(e2);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue