Search in sources :

Example 1 with JumpToken

use of org.eclipse.n4js.flowgraphs.model.JumpToken in project n4js by eclipse.

the class BinaryLogicalExpressionFactory method buildComplexNode.

static ComplexNode buildComplexNode(ReentrantASTIterator astpp, BinaryLogicalExpression lbExpr) {
    ComplexNode cNode = new ComplexNode(astpp.container(), lbExpr);
    HelperNode entryNode = new HelperNode(NodeNames.ENTRY, astpp.pos(), lbExpr);
    Node lhsNode = DelegatingNodeFactory.createOrHelper(astpp, NodeNames.LHS, lbExpr, lbExpr.getLhs());
    Node scJumpNode = new HelperNode(NodeNames.SHORT_CIRCUIT_JUMP, astpp.pos(), lbExpr);
    Node rhsNode = DelegatingNodeFactory.createOrHelper(astpp, NodeNames.RHS, lbExpr, lbExpr.getRhs());
    Node exitNode = new RepresentingNode(NodeNames.EXIT, astpp.pos(), lbExpr);
    cNode.addNode(entryNode);
    cNode.addNode(lhsNode);
    cNode.addNode(scJumpNode);
    cNode.addNode(rhsNode);
    cNode.addNode(exitNode);
    ControlFlowType thenCFT = null;
    ControlFlowType elseCFT = null;
    switch(lbExpr.getOp()) {
        case OR:
            thenCFT = ControlFlowType.IfFalse;
            elseCFT = ControlFlowType.IfTrue;
            break;
        case AND:
            thenCFT = ControlFlowType.IfTrue;
            elseCFT = ControlFlowType.IfFalse;
            break;
    }
    cNode.connectInternalSucc(entryNode, lhsNode, scJumpNode);
    cNode.connectInternalSucc(thenCFT, scJumpNode, rhsNode);
    cNode.connectInternalSucc(rhsNode, exitNode);
    // short-circuit evaluation
    scJumpNode.addJumpToken(new JumpToken(elseCFT));
    cNode.setJumpNode(scJumpNode);
    cNode.setEntryNode(entryNode);
    cNode.setExitNode(exitNode);
    rhsNode.addCatchToken(new CatchToken(thenCFT));
    boolean isCatchingLhs = isTopJumpCatcher(lbExpr);
    if (isCatchingLhs) {
        exitNode.addCatchToken(new CatchToken(elseCFT));
        exitNode.addCatchToken(new CatchToken(thenCFT));
    } else {
    // TODO: minor improvement: add the following jump node
    // exitNode.addJumpToken(new JumpToken(thenCFT)); // short-circuit evaluation
    // cNode.setJumpNode(scJumpNode);
    }
    return cNode;
}
Also used : JumpToken(org.eclipse.n4js.flowgraphs.model.JumpToken) HelperNode(org.eclipse.n4js.flowgraphs.model.HelperNode) ComplexNode(org.eclipse.n4js.flowgraphs.model.ComplexNode) ControlFlowType(org.eclipse.n4js.flowgraphs.ControlFlowType) HelperNode(org.eclipse.n4js.flowgraphs.model.HelperNode) RepresentingNode(org.eclipse.n4js.flowgraphs.model.RepresentingNode) ComplexNode(org.eclipse.n4js.flowgraphs.model.ComplexNode) Node(org.eclipse.n4js.flowgraphs.model.Node) RepresentingNode(org.eclipse.n4js.flowgraphs.model.RepresentingNode) CatchToken(org.eclipse.n4js.flowgraphs.model.CatchToken)

Example 2 with JumpToken

use of org.eclipse.n4js.flowgraphs.model.JumpToken in project n4js by eclipse.

the class FinallyFlowContext method findFinallyBlockContextEdge.

/**
 * This method searches all FinallyBlock-entry/exit edges E to chose the correct next following edges. The following
 * rules are implemented:
 * <ul>
 * <li/>If there exists no next edge with a context, then null is returned.
 * <li/>If there exists a next edge with a context, and the current {@link EdgeGuide} instance has no context that
 * matches with one of the next edges, then all edges without context are returned.
 * <li/>If there exists a next edge with a context, and the current {@link EdgeGuide} instance has a context that
 * matches with one of the next edges, the matching edge is returned.
 * </ul>
 */
private List<ControlFlowEdge> findFinallyBlockContextEdge(List<ControlFlowEdge> nextEdges) {
    LinkedList<ControlFlowEdge> fbContextFreeEdges = new LinkedList<>();
    Map<JumpToken, ControlFlowEdge> contextEdges = new HashMap<>();
    mapFinallyBlockContextEdges(nextEdges, fbContextFreeEdges, contextEdges);
    if (contextEdges.isEmpty()) {
        return Lists.newLinkedList();
    }
    ControlFlowEdge matchedFBContextEdge = null;
    Map.Entry<JumpToken, ControlFlowEdge> otherEdgePair = null;
    for (Map.Entry<JumpToken, ControlFlowEdge> ctxEdgePair : contextEdges.entrySet()) {
        JumpToken fbContext = ctxEdgePair.getKey();
        otherEdgePair = ctxEdgePair;
        if (finallyBlockContexts.contains(fbContext)) {
            matchedFBContextEdge = ctxEdgePair.getValue();
        }
    }
    if (matchedFBContextEdge != null) {
        return Collections2.newLinkedList(matchedFBContextEdge);
    } else if (!fbContextFreeEdges.isEmpty()) {
        return fbContextFreeEdges;
    } else if (otherEdgePair != null) {
        LinkedList<ControlFlowEdge> contextAndDeadEdges = new LinkedList<>();
        contextAndDeadEdges.add(otherEdgePair.getValue());
        for (ControlFlowEdge edge : nextEdges) {
            if (edge.cfType == ControlFlowType.DeadCode) {
                contextAndDeadEdges.add(edge);
            }
        }
        return contextAndDeadEdges;
    }
    return null;
}
Also used : JumpToken(org.eclipse.n4js.flowgraphs.model.JumpToken) ControlFlowEdge(org.eclipse.n4js.flowgraphs.model.ControlFlowEdge) HashMap(java.util.HashMap) Map(java.util.Map) HashMap(java.util.HashMap) LinkedList(java.util.LinkedList)

Aggregations

JumpToken (org.eclipse.n4js.flowgraphs.model.JumpToken)2 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 ControlFlowType (org.eclipse.n4js.flowgraphs.ControlFlowType)1 CatchToken (org.eclipse.n4js.flowgraphs.model.CatchToken)1 ComplexNode (org.eclipse.n4js.flowgraphs.model.ComplexNode)1 ControlFlowEdge (org.eclipse.n4js.flowgraphs.model.ControlFlowEdge)1 HelperNode (org.eclipse.n4js.flowgraphs.model.HelperNode)1 Node (org.eclipse.n4js.flowgraphs.model.Node)1 RepresentingNode (org.eclipse.n4js.flowgraphs.model.RepresentingNode)1