use of org.eclipse.n4js.flowgraphs.ControlFlowType 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;
}
use of org.eclipse.n4js.flowgraphs.ControlFlowType in project n4js by eclipse.
the class CatchNodeFinder method find.
/**
* @return the node to which the given {@code jumpNode} jumps via the given {@link JumpToken}. Can return null.
*/
static Pair<Node, ControlFlowType> find(JumpToken jumpToken, Node jumpNode, ComplexNodeMapper cnMapper) {
CatchEvaluator catchEvaluator = getCatchEvaluator(jumpToken);
ControlFlowElement cfe = jumpNode.getControlFlowElement();
cfe = skipContainers(cfe);
ControlFlowElement lastCFE = null;
while (cfe != null) {
Pair<Node, ControlFlowType> catcher = findCatchNode(jumpToken, cfe, lastCFE, catchEvaluator, cnMapper);
if (catcher != null)
return catcher;
lastCFE = cfe;
cfe = getContainer(cfe);
}
return null;
}
use of org.eclipse.n4js.flowgraphs.ControlFlowType in project n4js by eclipse.
the class ControlFlowGraphFactory method connectNode.
/**
* Connects all nodes based on
* <ul>
* <li/>the delegating nodes, and
* <li/>the internal successor information of each node.
* </ul>
*/
private static void connectNode(ComplexNodeMapper cnMapper, Node mNode) {
Node internalStartNode = mNode;
ControlFlowElement subASTElem = mNode.getDelegatedControlFlowElement();
if (subASTElem != null) {
ComplexNode subCN = cnMapper.get(subASTElem);
if (subCN != null) {
// can be null in case of malformed AST
EdgeUtils.connectCF(mNode, subCN.getEntry());
internalStartNode = subCN.getExit();
}
}
Set<Node> internalSuccs = mNode.getInternalSuccessors();
for (Node internalSucc : internalSuccs) {
ControlFlowType cfType = mNode.getInternalSuccessorControlFlowType(internalSucc);
EdgeUtils.connectCF(internalStartNode, internalSucc, cfType);
}
}
use of org.eclipse.n4js.flowgraphs.ControlFlowType in project n4js by eclipse.
the class ControlFlowGraphFactory method connectToJumpTarget.
private static void connectToJumpTarget(ComplexNodeMapper cnMapper, Node jumpNode, JumpToken jumpToken) {
Pair<Node, ControlFlowType> catcher = CatchNodeFinder.find(jumpToken, jumpNode, cnMapper);
if (catcher == null) {
String jumpTokenStr = getJumpTokenDetailString(jumpToken, jumpNode);
System.err.println("Could not find catching node for jump token '" + jumpTokenStr + "'");
return;
}
Node catchNode = catcher.getKey();
ControlFlowType newEdgeType = catcher.getValue();
FinallyBlock enteringFinallyBlock = getEnteringFinallyBlock(catchNode);
boolean isExitingFinallyBlock = isExitingFinallyBlock(cnMapper, jumpNode);
if (enteringFinallyBlock != null || isExitingFinallyBlock) {
boolean equalEdgeExistsAlready = equalEdgeExistsAlready(jumpNode, jumpToken, catchNode);
if (!equalEdgeExistsAlready) {
EdgeUtils.connectCF(jumpNode, catchNode, jumpToken);
}
} else {
EdgeUtils.connectCF(jumpNode, catchNode, newEdgeType);
}
if (enteringFinallyBlock != null) {
// Iff finally block was entered abruptly, jump on from exit of finally block
Block block = enteringFinallyBlock.getBlock();
ComplexNode cnBlock = cnMapper.get(block);
Node exitFinallyBlock = cnBlock.getExit();
connectToJumpTarget(cnMapper, exitFinallyBlock, jumpToken);
}
}
Aggregations