use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.
the class ControlFlowEdger method addCastExpressionEdges.
private List<ExitEdge> addCastExpressionEdges(Dag dag, DagNode node, LexicalScope scope) {
CastExpression ce = (CastExpression) node.astNode;
DagNode expressionDag = getDagChild(node.children, ce.getExpression(), null);
DagNode typeDag = getDagChild(node.children, ce.getType(), null);
node.gvAttributes.put("type", ce.getType().toString());
Rejigger rejigger = hoistNode(dag, node, expressionDag);
List<ExitEdge> prevNodes = addExpressionEdges(dag, expressionDag, scope);
/*
if (typeDag != null) { // types have Names, which are also expressions, but they're inside the ast node so typeDag is null
for (DagEdge e : prevNodes) {
e.n2 = typeDag;
}
ExitEdge e = new ExitEdge();
e.n1 = typeDag;
prevNodes = Collections.singletonList(e);
}
*/
prevNodes = rejigger.unhoistNode(dag, prevNodes);
return prevNodes;
}
use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.
the class ControlFlowEdger method addTypeDeclarationEdges.
private List<ExitEdge> addTypeDeclarationEdges(Dag dag, DagNode typeNode, LexicalScope scope) {
TypeDeclaration td = (TypeDeclaration) typeNode.astNode;
// method.label = "method " + md.getName();
if (td.isInterface()) {
typeNode.classes.add("interface");
typeNode.gvAttributes.put("interfaceName", td.getName().toString());
} else {
typeNode.classes.add("class");
typeNode.gvAttributes.put("className", td.getName().toString());
}
LexicalScope lexicalScope = scope.newTypeScope();
List<DagNode> bodyDeclarationDags = getDagChildren(typeNode.children, td.bodyDeclarations(), null);
// yeesh what about the static initializers. what about them indeed.
for (DagNode n : bodyDeclarationDags) {
// System.out.println(n.type);
// other type declarations and method declarations, it looks like
addEdges(dag, n, lexicalScope);
}
return Collections.emptyList();
}
use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.
the class ControlFlowEdger method addForEdges.
// draw branches into and out of for body
private List<ExitEdge> addForEdges(Dag dag, DagNode forNode, LexicalScope scope) {
// draw the edges
ForStatement fs = (ForStatement) forNode.astNode;
List<DagNode> initialiserDags = getDagChildren(forNode.children, fs.initializers(), "initialiser");
DagNode exprDag = getDagChild(forNode.children, fs.getExpression(), "expression");
List<DagNode> updaterDags = getDagChildren(forNode.children, fs.updaters(), "updater");
DagNode repeatingBlock = getDagChild(forNode.children, fs.getBody(), null);
// move forStatement node after the initialisation & expression nodes
Rejigger rejigger = hoistNode(dag, forNode, initialiserDags.size() == 0 ? exprDag : initialiserDags.get(0));
// expression is null for method calls within the same object
List<ExitEdge> prevNodes = null;
for (DagNode i : initialiserDags) {
if (prevNodes != null) {
for (ExitEdge e : prevNodes) {
e.n2 = i;
addEdge(e);
}
}
prevNodes = addExpressionEdges(dag, i, scope);
}
DagEdge firstExpressionEdge = null;
if (prevNodes != null) {
for (ExitEdge e : prevNodes) {
e.n2 = exprDag;
addEdge(e);
firstExpressionEdge = e;
}
}
prevNodes = addExpressionEdges(dag, exprDag, scope);
// this is the node we loop back to
DagNode firstExpressionNode = firstExpressionEdge == null ? rejigger.inEdge.n2 : firstExpressionEdge.n2;
prevNodes = rejigger.unhoistNode(dag, prevNodes);
DagEdge forTrue = prevNodes.get(0);
forTrue.classes.add("for");
forTrue.classes.add("true");
forTrue.n2 = repeatingBlock;
addEdge(forTrue);
LexicalScope newScope = scope.newBreakContinueScope(forNode, firstExpressionNode);
prevNodes = addEdges(dag, repeatingBlock, newScope);
for (DagNode u : updaterDags) {
for (ExitEdge e : prevNodes) {
e.n2 = u;
addEdge(e);
}
prevNodes = addExpressionEdges(dag, u, scope);
}
for (ExitEdge e : prevNodes) {
// exprDag
DagEdge backEdge = dag.addBackEdge(e.n1, firstExpressionNode, null);
backEdge.classes.add("for");
}
// the entire for
prevNodes = new ArrayList<>();
// prevNodes.addAll(repeatingBlockPrevNodes); // could add hidden edges here to force the 'after loop' nodes to appear under the for
// forward edges for any breaks inside the for scoped to this for
prevNodes.addAll(newScope.breakEdges);
ExitEdge forFalse = new ExitEdge();
forFalse.n1 = forNode;
forFalse.classes.add("for");
forFalse.classes.add("false");
prevNodes.add(forFalse);
return prevNodes;
}
use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.
the class ControlFlowEdger method addFieldAccessEdges.
// QualifiedNames e.g. "a.b.c" can also be represented as FieldAccess chains
// "this.i" becomes -> this -> field i
private List<ExitEdge> addFieldAccessEdges(Dag dag, DagNode node, LexicalScope scope) {
FieldAccess fa = (FieldAccess) node.astNode;
// includes things like += as well
DagNode exprDag = getDagChild(node.children, fa.getExpression(), null);
// DagNode fieldDag = getDagChild(node.children, fa.getName(), null); // will put the name on the FA node
node.gvAttributes.put("fieldName", fa.getName().toString());
Rejigger rejigger = hoistNode(dag, node, exprDag);
List<ExitEdge> prevNodes = addExpressionEdges(dag, exprDag, scope);
prevNodes = rejigger.unhoistNode(dag, prevNodes);
return prevNodes;
}
use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.
the class ControlFlowEdger method addReturnEdges.
// a return will add an edge to returnEdges only
// (and returns an empty list as we won't have a normal exit edge)
private List<ExitEdge> addReturnEdges(Dag dag, DagNode node, LexicalScope scope) {
ReturnStatement rs = (ReturnStatement) node.astNode;
DagNode expressionDag = getDagChild(node.children, rs.getExpression(), null);
// the expressionDag is after the return in the AST, but we want to evaluate it before the
// return statement (which already has edges leading to it), so we 'hoist' it above the
// return node in the DAG. This process is one of the 'rejiggering' operations.
// The opposite process when we add the return node back in is called 'unhoisting'.
ExitEdge e;
if (expressionDag != null) {
Rejigger rejigger = hoistNode(dag, node, expressionDag);
List<ExitEdge> prevNodes = addExpressionEdges(dag, expressionDag, scope);
prevNodes = rejigger.unhoistNode(dag, prevNodes);
if (prevNodes.size() != 1) {
throw new IllegalStateException("expected 1 exitEdge");
}
e = prevNodes.get(0);
} else {
e = new ExitEdge();
e.n1 = node;
}
e.classes.add("return");
scope.returnEdges.add(e);
return Collections.emptyList();
}
Aggregations