Search in sources :

Example 11 with DagNode

use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.

the class ControlFlowEdger method addInstanceofExpressionEdges.

private List<ExitEdge> addInstanceofExpressionEdges(Dag dag, DagNode node, LexicalScope scope) {
    InstanceofExpression ioe = (InstanceofExpression) node.astNode;
    DagNode expressionDag = getDagChild(node.children, ioe.getLeftOperand(), null);
    DagNode typeDag = getDagChild(node.children, ioe.getRightOperand(), null);
    node.gvAttributes.put("type", ioe.getRightOperand().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;
}
Also used : DagNode(com.randomnoun.build.javaToGraphviz.dag.DagNode) ExitEdge(com.randomnoun.build.javaToGraphviz.dag.ExitEdge) InstanceofExpression(org.eclipse.jdt.core.dom.InstanceofExpression)

Example 12 with DagNode

use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.

the class ControlFlowEdger method addClassInstanceCreationEdges.

private List<ExitEdge> addClassInstanceCreationEdges(Dag dag, DagNode node, LexicalScope scope) {
    ClassInstanceCreation cic = (ClassInstanceCreation) node.astNode;
    // maybe we evaluate the index first ? not sure. reckon it's probably the array ref
    DagNode expressionDag = getDagChild(node.children, cic.getExpression(), null);
    List<DagNode> argumentDags = getDagChildren(node.children, cic.arguments(), null);
    DagNode anonClassDag = getDagChild(node.children, cic.getAnonymousClassDeclaration(), "anonymousClass");
    // AnonymousClassDeclaration
    node.gvAttributes.put("type", cic.getType().toString());
    // DagNode indexDag = getDagChild(node.children, fa.getIndex(), null);
    // DagNode fieldDag = getDagChild(node.children, fa.getName(), null); // will put the name on the FA node
    List<ExitEdge> prevNodes = null;
    if (expressionDag != null || argumentDags.size() > 0) {
        // move methodInvocation node after the expression & argument nodes
        Rejigger rejigger = hoistNode(dag, node, expressionDag != null ? expressionDag : argumentDags.get(0));
        // expression is null for method calls within the same object
        if (expressionDag != null) {
            prevNodes = addExpressionEdges(dag, expressionDag, scope);
        }
        for (DagNode a : argumentDags) {
            if (prevNodes != null) {
                for (ExitEdge e : prevNodes) {
                    e.n2 = a;
                    e.classes.add("invocationArgument");
                    addEdge(e);
                }
            }
            prevNodes = addExpressionEdges(dag, a, scope);
        }
        prevNodes = rejigger.unhoistNode(dag, prevNodes);
    } else {
        ExitEdge e = new ExitEdge();
        e.n1 = node;
        prevNodes = Collections.singletonList(e);
    }
    // jam the anonymous class in here as if it was a lambda, but with methods like a class
    if (anonClassDag != null) {
        for (ExitEdge e : prevNodes) {
            e.n2 = anonClassDag;
            addEdge(e);
        }
        AnonymousClassDeclaration acdNode = (AnonymousClassDeclaration) anonClassDag.astNode;
        List<DagNode> bodyDeclarationDags = getDagChildren(anonClassDag.children, acdNode.bodyDeclarations(), null);
        LexicalScope lexicalScope = scope.newTypeScope();
        // add edges for everything in the class
        // @TODO check fields don't appear though. unless they initalise things, then maybe. Or maybe that goes into the constructors.
        // or not.
        // yeesh what about the static initializers. what about them indeed.
        List<ExitEdge> ees = new ArrayList<>();
        for (DagNode n : bodyDeclarationDags) {
            // add a transparent edge to each thing defined in this class so that the 'AnonymousClassDeclaration' node appears above them
            DagEdge e = addEdge(anonClassDag, n);
            e.classes.add("anonymousClassDeclarationBegin");
            ees.addAll(addEdges(dag, n, lexicalScope));
        }
        // add an artificial node so we can create an edge out of this thing
        CompilationUnit cu = ASTResolving.findParentCompilationUnit(acdNode);
        int endOfAnonClassLine = cu.getLineNumber(acdNode.getStartPosition() + acdNode.getLength());
        DagNode returnNode = new DagNode();
        returnNode.keepNode = anonClassDag.keepNodeMatcher.matches("anonymousClassDeclarationEnd");
        returnNode.type = "anonymousClassDeclarationEnd";
        returnNode.lineNumber = endOfAnonClassLine;
        // rn.name = dag.getUniqueName("m_" + endOfMethodLine);
        returnNode.classes.add("anonymousClassDeclaration");
        returnNode.classes.add("end");
        // rn.label = "return";
        returnNode.astNode = null;
        // include the artificial return inside the lambda grouping
        anonClassDag.children.add(returnNode);
        DagSubgraph sg = dag.dagNodeToSubgraph.get(anonClassDag);
        dag.addNode(sg, returnNode);
        for (ExitEdge ee : ees) {
            // add a transparent edge from each thing defined in this class to the artifical node
            // so that it appears underneath them
            ee.n2 = returnNode;
            ee.classes.add("anonymousClassDeclarationEnd");
            addEdge(ee);
        }
        // there's no exit edges out of an anonymous class
        // this gets truncated to the subgraph boundary in some css
        ExitEdge e = new ExitEdge();
        e.n1 = returnNode;
        prevNodes = Collections.singletonList(e);
    }
    return prevNodes;
}
Also used : ClassInstanceCreation(org.eclipse.jdt.core.dom.ClassInstanceCreation) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) AnonymousClassDeclaration(org.eclipse.jdt.core.dom.AnonymousClassDeclaration) ArrayList(java.util.ArrayList) DagSubgraph(com.randomnoun.build.javaToGraphviz.dag.DagSubgraph) DagNode(com.randomnoun.build.javaToGraphviz.dag.DagNode) ExitEdge(com.randomnoun.build.javaToGraphviz.dag.ExitEdge) DagEdge(com.randomnoun.build.javaToGraphviz.dag.DagEdge)

Example 13 with DagNode

use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.

the class ControlFlowEdger method addBlockEdges.

// draw lines from each statement to each other
// exit node is the last statement
private List<ExitEdge> addBlockEdges(Dag dag, DagNode block, LexicalScope scope) {
    // draw the edges from the block
    ExitEdge start = new ExitEdge();
    start.n1 = block;
    List<ExitEdge> prevNodes = Collections.singletonList(start);
    for (DagNode c : block.children) {
        if (!c.skipNode) {
            for (ExitEdge e : prevNodes) {
                e.n2 = c;
                addEdge(e);
            }
            prevNodes = addEdges(dag, c, scope);
        }
    }
    return prevNodes;
}
Also used : DagNode(com.randomnoun.build.javaToGraphviz.dag.DagNode) ExitEdge(com.randomnoun.build.javaToGraphviz.dag.ExitEdge)

Example 14 with DagNode

use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.

the class ControlFlowEdger method addLambdaExpressionEdges.

private List<ExitEdge> addLambdaExpressionEdges(Dag dag, DagNode lambdaNode, LexicalScope scope) {
    // lambda expression is going to be a big like a method declaration in the middle of a method.
    // but has an exit edge
    LambdaExpression le = (LambdaExpression) lambdaNode.astNode;
    // method.label = "method " + md.getName();
    // method.gvAttributes.put("methodName",  md.getName().toString());
    // we don't create nodes for method parameters yet, so not going to do that for lambdas either
    // (maybe we should ? )
    // when a lambda is defined control flow doesn't pass to the block,
    // so maybe I skip all of that somehow. OK so let's create an edge so it's grouped together but hide it in the diagram.
    DagNode blockNode = lambdaNode.children.get(lambdaNode.children.size() - 1);
    DagEdge lambdaEntryEdge = addEdge(lambdaNode, blockNode);
    lambdaEntryEdge.classes.add("lambdaEntry");
    // @TODO these probably need a new lexical scope
    LexicalScope lexicalScope = scope.newLambdaScope();
    List<ExitEdge> ee;
    if (blockNode.type.equals("Block")) {
        ee = addBlockEdges(dag, blockNode, lexicalScope);
    } else if (blockNode.astNode instanceof Expression) {
        ee = addExpressionEdges(dag, blockNode, lexicalScope);
    } else {
        throw new IllegalStateException("expected Block or Expression in lambda");
    }
    // add a node which all the return edges return to
    // this is an artificial node so maybe only construct it based on some gv declaration earlier on ?
    // (whereas all the other nodes are about as concrete as anything else in IT)
    // CompilationUnit cu = methodBlock.astNode.getParent();
    CompilationUnit cu = ASTResolving.findParentCompilationUnit(le);
    int endOfLambdaLine = cu.getLineNumber(le.getStartPosition() + le.getLength());
    DagNode returnNode = new DagNode();
    returnNode.keepNode = lambdaNode.keepNodeMatcher.matches("lambdaExpressionEnd");
    // label this 'end' if it has no return value ?
    returnNode.type = "lambdaExpressionEnd";
    returnNode.lineNumber = endOfLambdaLine;
    // rn.name = dag.getUniqueName("m_" + endOfMethodLine);
    returnNode.classes.add("lambdaExpression");
    returnNode.classes.add("end");
    // rn.label = "return";
    returnNode.astNode = null;
    // include the artificial return inside the lambda grouping
    lambdaNode.children.add(returnNode);
    DagSubgraph sg = dag.dagNodeToSubgraph.get(lambdaNode);
    dag.addNode(sg, returnNode);
    for (ExitEdge e : lexicalScope.returnEdges) {
        e.n2 = returnNode;
        addEdge(e);
    }
    for (ExitEdge e : ee) {
        e.n2 = returnNode;
        addEdge(e);
    }
    // and everything that was thrown connects to this node as well
    for (ExitEdge e : lexicalScope.throwEdges) {
        e.n2 = returnNode;
        addEdge(e);
    }
    // there's no exit edges out of a method, but let's say there is from a lambda
    // (it's not a real edge, it gets truncated to the subgraph boundary in some css)
    ExitEdge e = new ExitEdge();
    e.n1 = returnNode;
    return Collections.singletonList(e);
}
Also used : CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) DagNode(com.randomnoun.build.javaToGraphviz.dag.DagNode) ConditionalExpression(org.eclipse.jdt.core.dom.ConditionalExpression) InstanceofExpression(org.eclipse.jdt.core.dom.InstanceofExpression) ThisExpression(org.eclipse.jdt.core.dom.ThisExpression) Expression(org.eclipse.jdt.core.dom.Expression) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) CastExpression(org.eclipse.jdt.core.dom.CastExpression) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) PostfixExpression(org.eclipse.jdt.core.dom.PostfixExpression) ParenthesizedExpression(org.eclipse.jdt.core.dom.ParenthesizedExpression) LambdaExpression(org.eclipse.jdt.core.dom.LambdaExpression) PrefixExpression(org.eclipse.jdt.core.dom.PrefixExpression) ExitEdge(com.randomnoun.build.javaToGraphviz.dag.ExitEdge) DagSubgraph(com.randomnoun.build.javaToGraphviz.dag.DagSubgraph) LambdaExpression(org.eclipse.jdt.core.dom.LambdaExpression) DagEdge(com.randomnoun.build.javaToGraphviz.dag.DagEdge)

Example 15 with DagNode

use of com.randomnoun.build.javaToGraphviz.dag.DagNode in project java-to-graphviz by randomnoun.

the class ControlFlowEdger method addVariableDeclarationStatementEdges.

private List<ExitEdge> addVariableDeclarationStatementEdges(Dag dag, DagNode node, LexicalScope scope) {
    // modifiers, type, varDecFragments
    VariableDeclarationStatement vs = (VariableDeclarationStatement) node.astNode;
    List<DagNode> fragments = getDagChildren(node.children, vs.fragments(), null);
    node.gvAttributes.put("type", vs.getType().toString());
    ExitEdge e = new ExitEdge();
    e.n1 = node;
    List<ExitEdge> prevNodes = Collections.singletonList(e);
    for (DagNode f : fragments) {
        for (ExitEdge pe : prevNodes) {
            pe.n2 = f;
            dag.edges.add(pe);
        }
        e = new ExitEdge();
        e.n1 = f;
        prevNodes = Collections.singletonList(e);
        // name, dimension(s), expression
        VariableDeclarationFragment vdf = (VariableDeclarationFragment) f.astNode;
        DagNode expressionDag = getDagChild(f.children, vdf.getInitializer(), null);
        if (expressionDag != null) {
            Rejigger rejigger = hoistNode(dag, f, expressionDag);
            prevNodes = addExpressionEdges(dag, expressionDag, scope);
            prevNodes = rejigger.unhoistNode(dag, prevNodes);
        }
        f.gvAttributes.put("type", vs.getType().toString());
        f.gvAttributes.put("variableName", vdf.getName().toString());
    }
    return prevNodes;
}
Also used : DagNode(com.randomnoun.build.javaToGraphviz.dag.DagNode) ExitEdge(com.randomnoun.build.javaToGraphviz.dag.ExitEdge) VariableDeclarationFragment(org.eclipse.jdt.core.dom.VariableDeclarationFragment) VariableDeclarationStatement(org.eclipse.jdt.core.dom.VariableDeclarationStatement)

Aggregations

DagNode (com.randomnoun.build.javaToGraphviz.dag.DagNode)55 ExitEdge (com.randomnoun.build.javaToGraphviz.dag.ExitEdge)33 DagEdge (com.randomnoun.build.javaToGraphviz.dag.DagEdge)20 DagSubgraph (com.randomnoun.build.javaToGraphviz.dag.DagSubgraph)11 ArrayList (java.util.ArrayList)8 DagElement (com.randomnoun.build.javaToGraphviz.dom.DagElement)6 GvComment (com.randomnoun.build.javaToGraphviz.comment.GvComment)3 ExceptionErrorHandler (com.randomnoun.build.javaToGraphviz.dom.StylesheetApplier.ExceptionErrorHandler)3 CSSOMParser (com.steadystate.css.parser.CSSOMParser)3 ASTNode (org.eclipse.jdt.core.dom.ASTNode)3 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)3 ConditionalExpression (org.eclipse.jdt.core.dom.ConditionalExpression)3 InfixExpression (org.eclipse.jdt.core.dom.InfixExpression)3 InstanceofExpression (org.eclipse.jdt.core.dom.InstanceofExpression)3 CommentText (com.randomnoun.build.javaToGraphviz.comment.CommentText)2 GvEndGraphComment (com.randomnoun.build.javaToGraphviz.comment.GvEndGraphComment)2 GvEndSubgraphComment (com.randomnoun.build.javaToGraphviz.comment.GvEndSubgraphComment)2 GvGraphComment (com.randomnoun.build.javaToGraphviz.comment.GvGraphComment)2 GvKeepNodeComment (com.randomnoun.build.javaToGraphviz.comment.GvKeepNodeComment)2 GvLiteralComment (com.randomnoun.build.javaToGraphviz.comment.GvLiteralComment)2