mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
- re-wrote to use labeled node instead of decisionArc
This commit is contained in:
parent
d346fcd041
commit
ee3a2444d1
16 changed files with 222 additions and 249 deletions
|
@ -20,6 +20,8 @@ import org.eclipse.cdt.codan.internal.core.cfg.JumpNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
||||||
|
@ -27,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
|
@ -89,6 +92,8 @@ public class ControlFlowGraphBuilder {
|
||||||
return createWhile(prev, (IASTWhileStatement) body);
|
return createWhile(prev, (IASTWhileStatement) body);
|
||||||
} else if (body instanceof IASTForStatement) {
|
} else if (body instanceof IASTForStatement) {
|
||||||
return createFor(prev, (IASTForStatement) body);
|
return createFor(prev, (IASTForStatement) body);
|
||||||
|
} else if (body instanceof IASTDoStatement) {
|
||||||
|
return createDoWhile(prev, (IASTDoStatement) body);
|
||||||
} else if (body instanceof IASTReturnStatement) {
|
} else if (body instanceof IASTReturnStatement) {
|
||||||
CxxExitNode node = factory.createExitNode(body);
|
CxxExitNode node = factory.createExitNode(body);
|
||||||
node.setStartNode(start);
|
node.setStartNode(start);
|
||||||
|
@ -106,18 +111,20 @@ public class ControlFlowGraphBuilder {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected IBasicBlock createIf(IBasicBlock prev, IASTIfStatement body) {
|
protected IBasicBlock createIf(IBasicBlock prev, IASTIfStatement body) {
|
||||||
DecisionNode node = factory.createDecisionNode(body
|
DecisionNode ifNode = factory.createDecisionNode(body
|
||||||
.getConditionExpression());
|
.getConditionExpression());
|
||||||
addOutgoing(prev, node);
|
addOutgoing(prev, ifNode);
|
||||||
ConnectorNode conn = new ConnectorNode();
|
IConnectorNode mergeNode = factory.createConnectorNode();
|
||||||
node.setConnectorNode(conn);
|
ifNode.setMergeNode(mergeNode);
|
||||||
IBasicBlock els = createSubGraph(node, body.getElseClause());
|
ILabeledNode thenNode = factory.createLabeledNode(ILabeledNode.THEN);
|
||||||
conn.addIncoming(els);
|
addOutgoing(ifNode, thenNode);
|
||||||
addOutgoing(els, conn);
|
IBasicBlock then = createSubGraph(thenNode, body.getThenClause());
|
||||||
IBasicBlock then = createSubGraph(node, body.getThenClause());
|
addOutgoing(then, mergeNode);
|
||||||
conn.addIncoming(then);
|
ILabeledNode elseNode = factory.createLabeledNode(ILabeledNode.ELSE);
|
||||||
addOutgoing(then, conn);
|
addOutgoing(ifNode, elseNode);
|
||||||
return conn;
|
IBasicBlock els = createSubGraph(elseNode, body.getElseClause());
|
||||||
|
addOutgoing(els, mergeNode);
|
||||||
|
return mergeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,7 +137,7 @@ public class ControlFlowGraphBuilder {
|
||||||
.getControllerExpression());
|
.getControllerExpression());
|
||||||
addOutgoing(prev, node);
|
addOutgoing(prev, node);
|
||||||
ConnectorNode conn = new ConnectorNode();
|
ConnectorNode conn = new ConnectorNode();
|
||||||
node.setConnectorNode(conn);
|
node.setMergeNode(conn);
|
||||||
createSwitchBody(node, conn, body.getBody());
|
createSwitchBody(node, conn, body.getBody());
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
@ -148,20 +155,15 @@ public class ControlFlowGraphBuilder {
|
||||||
IASTCompoundStatement comp = (IASTCompoundStatement) body;
|
IASTCompoundStatement comp = (IASTCompoundStatement) body;
|
||||||
IASTNode[] children = comp.getChildren();
|
IASTNode[] children = comp.getChildren();
|
||||||
IBasicBlock prev = switchNode;
|
IBasicBlock prev = switchNode;
|
||||||
int labelNum = 1;
|
|
||||||
for (int i = 0; i < children.length; i++) {
|
for (int i = 0; i < children.length; i++) {
|
||||||
IASTNode elem = children[i];
|
IASTNode elem = children[i];
|
||||||
if (elem instanceof IASTCaseStatement) {
|
if (elem instanceof IASTCaseStatement) {
|
||||||
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
|
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
|
||||||
IPlainNode nextSt = factory
|
ILabeledNode lbl = factory.createLabeledNode(caseSt);
|
||||||
.createPlainNode();
|
|
||||||
if (!(prev instanceof IExitNode) && prev != switchNode)
|
if (!(prev instanceof IExitNode) && prev != switchNode)
|
||||||
addOutgoing(prev, nextSt);
|
addOutgoing(prev, lbl);
|
||||||
switchNode.addOutgoing(new CxxDecisionArc(switchNode, labelNum,
|
addOutgoing(switchNode, lbl);
|
||||||
nextSt, caseSt));
|
prev = lbl;
|
||||||
labelNum++;
|
|
||||||
((AbstractBasicBlock)nextSt).addIncoming(switchNode);
|
|
||||||
prev = nextSt;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (elem instanceof IASTBreakStatement) {
|
if (elem instanceof IASTBreakStatement) {
|
||||||
|
@ -173,15 +175,12 @@ public class ControlFlowGraphBuilder {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (elem instanceof IASTDefaultStatement) {
|
if (elem instanceof IASTDefaultStatement) {
|
||||||
IASTDefaultStatement caseSt = (IASTDefaultStatement) elem;
|
ILabeledNode lbl = factory
|
||||||
IPlainNode nextSt = factory
|
.createLabeledNode(ILabeledNode.DEFAULT);
|
||||||
.createPlainNode();
|
|
||||||
if (!(prev instanceof IExitNode) && prev != switchNode)
|
if (!(prev instanceof IExitNode) && prev != switchNode)
|
||||||
addOutgoing(prev, nextSt);
|
addOutgoing(prev, lbl);
|
||||||
switchNode.addOutgoing(new CxxDecisionArc(switchNode, 0,
|
addOutgoing(switchNode, lbl);
|
||||||
nextSt, caseSt));
|
prev = lbl;
|
||||||
((AbstractBasicBlock)nextSt).addIncoming(switchNode);
|
|
||||||
prev = nextSt;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IBasicBlock last = createSubGraph(prev, elem);
|
IBasicBlock last = createSubGraph(prev, elem);
|
||||||
|
@ -209,19 +208,24 @@ public class ControlFlowGraphBuilder {
|
||||||
addOutgoing(nContinue2, decision);
|
addOutgoing(nContinue2, decision);
|
||||||
// add break connector
|
// add break connector
|
||||||
IConnectorNode nBreak = factory.createConnectorNode();
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
addOutgoing(decision, nBreak);
|
decision.setMergeNode(nBreak);
|
||||||
decision.setConnectorNode(nBreak);
|
|
||||||
// create body and jump to continue node
|
// create body and jump to continue node
|
||||||
IBasicBlock nBody = createSubGraph(decision, forNode.getBody());
|
ILabeledNode loopStart = factory.createLabeledNode(ILabeledNode.THEN);
|
||||||
|
addOutgoing(decision, loopStart);
|
||||||
|
IBasicBlock endBody = createSubGraph(loopStart, forNode.getBody());
|
||||||
// inc
|
// inc
|
||||||
IPlainNode inc = factory.createPlainNode(forNode
|
IPlainNode inc = factory.createPlainNode(forNode
|
||||||
.getIterationExpression());
|
.getIterationExpression());
|
||||||
addOutgoing(nBody, inc);
|
addOutgoing(endBody, inc);
|
||||||
JumpNode jumpContinue = new JumpNode();
|
JumpNode jumpContinue = new JumpNode();
|
||||||
addOutgoing(inc, jumpContinue);
|
addOutgoing(inc, jumpContinue);
|
||||||
jumpContinue.setJump(nContinue2, true);
|
jumpContinue.setJump(nContinue2, true);
|
||||||
// connect with backward link
|
// connect with backward link
|
||||||
addOutgoing(jumpContinue, nContinue2);
|
addOutgoing(jumpContinue, nContinue2);
|
||||||
|
// add "else" branch
|
||||||
|
ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE);
|
||||||
|
addOutgoing(decision, loopEnd);
|
||||||
|
addOutgoing(loopEnd, nBreak);
|
||||||
return nBreak;
|
return nBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,15 +244,50 @@ public class ControlFlowGraphBuilder {
|
||||||
addOutgoing(nContinue, decision);
|
addOutgoing(nContinue, decision);
|
||||||
// add break connector
|
// add break connector
|
||||||
IConnectorNode nBreak = factory.createConnectorNode();
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
addOutgoing(decision, nBreak);
|
decision.setMergeNode(nBreak);
|
||||||
decision.setConnectorNode(nBreak);
|
|
||||||
// create body and jump to continue node
|
// create body and jump to continue node
|
||||||
IBasicBlock nBody = createSubGraph(decision, body.getBody());
|
ILabeledNode loopStart = factory.createLabeledNode(ILabeledNode.THEN);
|
||||||
|
addOutgoing(decision, loopStart);
|
||||||
|
IBasicBlock endBody = createSubGraph(loopStart, body.getBody());
|
||||||
JumpNode jumpContinue = new JumpNode();
|
JumpNode jumpContinue = new JumpNode();
|
||||||
addOutgoing(nBody, jumpContinue);
|
addOutgoing(endBody, jumpContinue);
|
||||||
jumpContinue.setJump(nContinue, true);
|
jumpContinue.setJump(nContinue, true);
|
||||||
// connect with backward link
|
// connect with backward link
|
||||||
addOutgoing(jumpContinue, nContinue);
|
addOutgoing(jumpContinue, nContinue);
|
||||||
|
// connect with else branch
|
||||||
|
ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE);
|
||||||
|
addOutgoing(decision, loopEnd);
|
||||||
|
addOutgoing(loopEnd, nBreak);
|
||||||
|
return nBreak;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IBasicBlock createDoWhile(IBasicBlock prev, IASTDoStatement body) {
|
||||||
|
// create body and jump to continue node
|
||||||
|
IConnectorNode loopStart = factory.createConnectorNode();
|
||||||
|
addOutgoing(prev, loopStart);
|
||||||
|
IBasicBlock endBody = createSubGraph(loopStart, body.getBody());
|
||||||
|
// add continue connector
|
||||||
|
IConnectorNode nContinue = factory.createLabeledNode("continue");
|
||||||
|
addOutgoing(endBody, nContinue);
|
||||||
|
// decision node
|
||||||
|
CxxDecisionNode decision = factory.createDecisionNode(body
|
||||||
|
.getCondition());
|
||||||
|
addOutgoing(nContinue, decision);
|
||||||
|
// then branch
|
||||||
|
ILabeledNode thenNode = factory.createLabeledNode(ILabeledNode.THEN);
|
||||||
|
addOutgoing(decision, thenNode);
|
||||||
|
IJumpNode jumpToStart = factory.createJumpNode();
|
||||||
|
addOutgoing(thenNode, jumpToStart);
|
||||||
|
((JumpNode)jumpToStart).setBackward(true);
|
||||||
|
// connect with backward link
|
||||||
|
addOutgoing(jumpToStart, loopStart);
|
||||||
|
// connect with else branch
|
||||||
|
ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE);
|
||||||
|
addOutgoing(decision, loopEnd);
|
||||||
|
// add break connector
|
||||||
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
|
decision.setMergeNode(nBreak);
|
||||||
|
addOutgoing(loopEnd, nBreak);
|
||||||
return nBreak;
|
return nBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,26 +10,19 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.DecisionArc;
|
import org.eclipse.cdt.codan.internal.core.cfg.LabeledNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: add description
|
* TODO: add description
|
||||||
*/
|
*/
|
||||||
public class CxxDecisionArc extends DecisionArc {
|
public class CxxLabeledNode extends LabeledNode {
|
||||||
private IASTNode label;
|
private IASTNode labelData;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param decisionNode
|
CxxLabeledNode(IASTNode label) {
|
||||||
* @param i
|
super(label.getRawSignature());
|
||||||
* @param node
|
this.labelData = label;
|
||||||
*/
|
|
||||||
public CxxDecisionArc(DecisionNode decisionNode, int i, IBasicBlock node,
|
|
||||||
IASTNode label) {
|
|
||||||
super(decisionNode, i, node);
|
|
||||||
this.label = label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -39,6 +32,6 @@ public class CxxDecisionArc extends DecisionArc {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return label.getRawSignature();
|
return labelData.getRawSignature()+":";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
|
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.NodeFactory;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.NodeFactory;
|
||||||
|
@ -37,6 +38,7 @@ public class CxxNodeFactory extends NodeFactory implements INodeFactory {
|
||||||
public IExitNode createExitNode() {
|
public IExitNode createExitNode() {
|
||||||
return new CxxExitNode();
|
return new CxxExitNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CxxPlainNode createPlainNode(IASTNode ast) {
|
public CxxPlainNode createPlainNode(IASTNode ast) {
|
||||||
IPlainNode node = createPlainNode();
|
IPlainNode node = createPlainNode();
|
||||||
((AbstractBasicBlock) node).setData(ast);
|
((AbstractBasicBlock) node).setData(ast);
|
||||||
|
@ -48,9 +50,20 @@ public class CxxNodeFactory extends NodeFactory implements INodeFactory {
|
||||||
((AbstractBasicBlock) node).setData(ast);
|
((AbstractBasicBlock) node).setData(ast);
|
||||||
return (CxxDecisionNode) node;
|
return (CxxDecisionNode) node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CxxExitNode createExitNode(IASTNode ast) {
|
public CxxExitNode createExitNode(IASTNode ast) {
|
||||||
IExitNode node = createExitNode();
|
IExitNode node = createExitNode();
|
||||||
((AbstractBasicBlock) node).setData(ast);
|
((AbstractBasicBlock) node).setData(ast);
|
||||||
return (CxxExitNode) node;
|
return (CxxExitNode) node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param caseSt
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ILabeledNode createLabeledNode(IASTNode caseSt) {
|
||||||
|
ILabeledNode node = createLabeledNode(caseSt.getRawSignature());
|
||||||
|
((AbstractBasicBlock) node).setData(caseSt);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class ControlFlowGraphTest extends CodanTestCase {
|
||||||
}
|
}
|
||||||
if (node instanceof IDecisionNode) {
|
if (node instanceof IDecisionNode) {
|
||||||
assertTrue("decision node outgping size",node.getOutgoingSize()>1);
|
assertTrue("decision node outgping size",node.getOutgoingSize()>1);
|
||||||
assertNotNull(((IDecisionNode) node).getConnectionNode());
|
assertNotNull(((IDecisionNode) node).getMergeNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,13 @@ import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
|
|
||||||
|
@ -71,22 +72,21 @@ public class ControlFlowGraph implements IControlFlowGraph {
|
||||||
public void print(IBasicBlock node) {
|
public void print(IBasicBlock node) {
|
||||||
System.out.println(node.getClass().getSimpleName() + ": "
|
System.out.println(node.getClass().getSimpleName() + ": "
|
||||||
+ ((AbstractBasicBlock) node).toStringData());
|
+ ((AbstractBasicBlock) node).toStringData());
|
||||||
if (node instanceof IConnectorNode)
|
|
||||||
if (((IConnectorNode) node).hasBackwardIncoming() == false)
|
|
||||||
return;
|
|
||||||
if (node instanceof IDecisionNode) {
|
if (node instanceof IDecisionNode) {
|
||||||
// todo
|
// todo
|
||||||
Iterator<IDecisionArc> decisionArcs = ((IDecisionNode) node)
|
Iterator<IBasicBlock> branches = ((IDecisionNode) node)
|
||||||
.getDecisionArcs();
|
.getOutgoingIterator();
|
||||||
for (; decisionArcs.hasNext();) {
|
for (; branches.hasNext();) {
|
||||||
IDecisionArc arc = decisionArcs.next();
|
IBasicBlock brNode = branches.next();
|
||||||
System.out.println("{" + arc.getIndex() + ":");
|
System.out.println("{");
|
||||||
print(arc.getOutgoing());
|
print(brNode);
|
||||||
System.out.println("}");
|
System.out.println("}");
|
||||||
}
|
}
|
||||||
print(((IDecisionNode) node).getConnectionNode());
|
print(((IDecisionNode) node).getMergeNode());
|
||||||
} else if (node instanceof ISingleOutgoing) {
|
} else if (node instanceof ISingleOutgoing) {
|
||||||
print(((ISingleOutgoing) node).getOutgoing());
|
IBasicBlock next = ((ISingleOutgoing) node).getOutgoing();
|
||||||
|
if (!(next instanceof IConnectorNode && !(next instanceof ILabeledNode)))
|
||||||
|
print(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Alena Laskavaia
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Alena Laskavaia - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.codan.internal.core.cfg;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
|
||||||
|
|
||||||
public class DecisionArc implements IDecisionArc {
|
|
||||||
private final DecisionNode decisionNode;
|
|
||||||
protected int index;
|
|
||||||
protected IBasicBlock node;
|
|
||||||
|
|
||||||
public DecisionArc(DecisionNode decisionNode, int i, IBasicBlock node) {
|
|
||||||
this.decisionNode = decisionNode;
|
|
||||||
this.index = i;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IBasicBlock getOutgoing() {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDecisionNode getDecisionNode() {
|
|
||||||
return this.decisionNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return index + "";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,14 +11,11 @@
|
||||||
package org.eclipse.cdt.codan.internal.core.cfg;
|
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +23,7 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
*/
|
*/
|
||||||
public class DecisionNode extends AbstractSingleIncomingNode implements
|
public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||||
IDecisionNode {
|
IDecisionNode {
|
||||||
private List<IDecisionArc> next = new ArrayList<IDecisionArc>(2);
|
private List<IBasicBlock> next = new ArrayList<IBasicBlock>(2);
|
||||||
private IConnectorNode conn;
|
private IConnectorNode conn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,39 +33,10 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDecisionArcs(Collection<IDecisionArc> next) {
|
|
||||||
this.next = Collections.unmodifiableList(new ArrayList<IDecisionArc>(
|
|
||||||
next));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addOutgoing(IBasicBlock node) {
|
public void addOutgoing(IBasicBlock node) {
|
||||||
DecisionArc arc = new DecisionArc(this, getDecisionArcSize(), node);
|
IConnectorNode cnode = (IConnectorNode) node; // cast to throw CCE
|
||||||
next.add(arc);
|
next.add(cnode);
|
||||||
}
|
|
||||||
|
|
||||||
public void addOutgoing(IDecisionArc arc) {
|
|
||||||
next.add(arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
|
||||||
* getDecisionArcs()
|
|
||||||
*/
|
|
||||||
public Iterator<IDecisionArc> getDecisionArcs() {
|
|
||||||
return next.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
|
||||||
* getDecisionArcSize()
|
|
||||||
*/
|
|
||||||
public int getDecisionArcSize() {
|
|
||||||
return next.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -78,25 +46,7 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||||
* getOutgoingIterator()
|
* getOutgoingIterator()
|
||||||
*/
|
*/
|
||||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||||
return new Iterator<IBasicBlock>() {
|
return next.iterator();
|
||||||
private Iterator<IDecisionArc> it;
|
|
||||||
{
|
|
||||||
it = next.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
return it.hasNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IBasicBlock next() {
|
|
||||||
IDecisionArc arc = it.next();
|
|
||||||
return arc.getOutgoing();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -116,11 +66,11 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
||||||
* getConnectionNode()
|
* getConnectionNode()
|
||||||
*/
|
*/
|
||||||
public IConnectorNode getConnectionNode() {
|
public IConnectorNode getMergeNode() {
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectorNode(IConnectorNode conn) {
|
public void setMergeNode(IConnectorNode conn) {
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJump(IConnectorNode jump, boolean backward) {
|
public void setJump(IConnectorNode jump, boolean backward) {
|
||||||
if (this.jump != null)
|
if (this.jump != null && this.jump != jump)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Cannot modify exiting connector"); //$NON-NLS-1$
|
"Cannot modify exiting connector"); //$NON-NLS-1$
|
||||||
this.jump = jump;
|
this.jump = jump;
|
||||||
|
@ -59,8 +59,6 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addOutgoing(IBasicBlock node) {
|
public void addOutgoing(IBasicBlock node) {
|
||||||
if (node == jump)
|
setJump((IConnectorNode) node, backward);
|
||||||
return;
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 Alena Laskavaia
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alena Laskavaia - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: add description
|
||||||
|
*/
|
||||||
|
public class LabeledNode extends ConnectorNode implements ILabeledNode {
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public LabeledNode(String label) {
|
||||||
|
super();
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode#getLabel()
|
||||||
|
*/
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toStringData() {
|
||||||
|
if (getData() == null)
|
||||||
|
return label + ":";
|
||||||
|
return getData().toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,31 +0,0 @@
|
||||||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arc that has a condition upon it, for example if branches have true/false
|
|
||||||
* condition, and switch branches have case condition
|
|
||||||
*/
|
|
||||||
public interface IDecisionArc extends ISingleOutgoing {
|
|
||||||
/**
|
|
||||||
* Index represent branch index in decision node, as well semantics: <br>
|
|
||||||
* 0 - always a false (else) branch of if, and default branch for switch,
|
|
||||||
* even if no code exists <br>
|
|
||||||
* 1 - is true (then) branch for if
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int getIndex();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic block that is at the end of the arc
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
IBasicBlock getOutgoing();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return parent node (decision node) or the decision arc
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
IDecisionNode getDecisionNode();
|
|
||||||
}
|
|
|
@ -1,17 +1,16 @@
|
||||||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Interface for decision node. This node represent condition node in the graph,
|
* Interface for decision node. This node represent condition node in the graph,
|
||||||
* it has one incoming arc and many outgoing, each of them has a value of
|
* it has one incoming arc and many outgoing, each of outgoing node should be
|
||||||
* condition associated with it.
|
* ILabeledNode
|
||||||
*/
|
*/
|
||||||
public interface IDecisionNode extends IBasicBlock, ISingleIncoming {
|
public interface IDecisionNode extends IBasicBlock, ISingleIncoming {
|
||||||
Iterator<IDecisionArc> getDecisionArcs();
|
/**
|
||||||
|
* Node where branches of decision node merge
|
||||||
int getDecisionArcSize();
|
*
|
||||||
|
* @return
|
||||||
IConnectorNode getConnectionNode();
|
*/
|
||||||
|
IConnectorNode getMergeNode();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 Alena Laskavaia
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alena Laskavaia - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Node that represent empty operator with label, such as case branch or label
|
||||||
|
*/
|
||||||
|
public interface ILabeledNode extends IConnectorNode {
|
||||||
|
public static String THEN = "then"; //$NON-NLS-1$
|
||||||
|
public static String ELSE = "else"; //$NON-NLS-1$
|
||||||
|
public static String DEFAULT = "default"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
String getLabel();
|
||||||
|
}
|
|
@ -22,6 +22,8 @@ public interface INodeFactory {
|
||||||
|
|
||||||
IConnectorNode createConnectorNode();
|
IConnectorNode createConnectorNode();
|
||||||
|
|
||||||
|
ILabeledNode createLabeledNode(String label);
|
||||||
|
|
||||||
IStartNode createStartNode();
|
IStartNode createStartNode();
|
||||||
|
|
||||||
IExitNode createExitNode();
|
IExitNode createExitNode();
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.eclipse.cdt.codan.internal.core.cfg.ConnectorNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.ExitNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.ExitNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.JumpNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.JumpNode;
|
||||||
|
import org.eclipse.cdt.codan.internal.core.cfg.LabeledNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.PlainNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.PlainNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.StartNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.StartNode;
|
||||||
|
|
||||||
|
@ -99,4 +100,8 @@ public class NodeFactory implements INodeFactory {
|
||||||
public IExitNode createExitNode() {
|
public IExitNode createExitNode() {
|
||||||
return new ExitNode();
|
return new ExitNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ILabeledNode createLabeledNode(String label) {
|
||||||
|
return new LabeledNode(label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
codan/org.eclipse.cdt.codan.ui.cfgview/icons/labeled.png
Normal file
BIN
codan/org.eclipse.cdt.codan.ui.cfgview/icons/labeled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 320 B |
|
@ -3,16 +3,17 @@ package org.eclipse.cdt.codan.ui.cfgview.views;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder;
|
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder;
|
||||||
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.CxxControlFlowGraph;
|
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.CxxControlFlowGraph;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
|
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
import org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin;
|
import org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin;
|
||||||
|
@ -120,22 +121,19 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
return blocks.toArray();
|
return blocks.toArray();
|
||||||
} else if (parent instanceof IDecisionNode) {
|
} else if (parent instanceof IDecisionNode) {
|
||||||
ArrayList blocks = new ArrayList();
|
ArrayList blocks = new ArrayList();
|
||||||
Iterator<IDecisionArc> iter = ((IDecisionNode) parent)
|
Iterator<IBasicBlock> iter = ((IDecisionNode) parent)
|
||||||
.getDecisionArcs();
|
.getOutgoingIterator();
|
||||||
if (iter.hasNext()) {
|
if (iter.hasNext()) {
|
||||||
IDecisionArc arc0 = iter.next();
|
|
||||||
for (; iter.hasNext();) {
|
for (; iter.hasNext();) {
|
||||||
IDecisionArc arc = iter.next();
|
IBasicBlock arc = iter.next();
|
||||||
blocks.add(arc);
|
blocks.add(arc);
|
||||||
}
|
}
|
||||||
blocks.add(arc0);// people naturally expect false branch
|
|
||||||
// after true
|
|
||||||
}
|
}
|
||||||
blocks.add(((IDecisionNode) parent).getConnectionNode());
|
blocks.add(((IDecisionNode) parent).getMergeNode());
|
||||||
return blocks.toArray();
|
return blocks.toArray();
|
||||||
} else if (parent instanceof IDecisionArc) {
|
} else if (parent instanceof ILabeledNode) {
|
||||||
Collection<IBasicBlock> blocks = getFlat(
|
Collection<IBasicBlock> blocks = getFlat(
|
||||||
((IDecisionArc) parent).getOutgoing(),
|
((ILabeledNode) parent).getOutgoing(),
|
||||||
new ArrayList<IBasicBlock>());
|
new ArrayList<IBasicBlock>());
|
||||||
return blocks.toArray();
|
return blocks.toArray();
|
||||||
}
|
}
|
||||||
|
@ -156,23 +154,13 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
strdata = ((AbstractBasicBlock) obj).toStringData();
|
strdata = ((AbstractBasicBlock) obj).toStringData();
|
||||||
}
|
}
|
||||||
if (strdata == null || strdata.length() == 0) {
|
if (strdata == null || strdata.length() == 0) {
|
||||||
if (obj instanceof IConnectorNode) {
|
if (obj instanceof ILabeledNode) {
|
||||||
|
strdata = strdata+blockHexLabel(obj);
|
||||||
|
} else if (obj instanceof IConnectorNode) {
|
||||||
strdata = blockHexLabel(obj);
|
strdata = blockHexLabel(obj);
|
||||||
} else if (obj instanceof IJumpNode) {
|
} else if (obj instanceof IJumpNode) {
|
||||||
strdata = blockHexLabel(((IJumpNode) obj).getJumpNode());
|
strdata = blockHexLabel(((IJumpNode) obj).getJumpNode());
|
||||||
} else if (obj instanceof IDecisionArc) {
|
}
|
||||||
IDecisionArc arc = (IDecisionArc) obj;
|
|
||||||
int index = arc.getIndex();
|
|
||||||
if (arc.getDecisionNode().getDecisionArcSize() == 2) {
|
|
||||||
if (index == 0)
|
|
||||||
strdata = "false";
|
|
||||||
else
|
|
||||||
strdata = "true";
|
|
||||||
} else if (index == 0)
|
|
||||||
strdata = "default";
|
|
||||||
else
|
|
||||||
strdata = "" + index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return obj.getClass().getSimpleName() + ": " + strdata;
|
return obj.getClass().getSimpleName() + ": " + strdata;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +184,8 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
imageKey = "start.png";
|
imageKey = "start.png";
|
||||||
else if (obj instanceof IJumpNode)
|
else if (obj instanceof IJumpNode)
|
||||||
imageKey = "jump.png";
|
imageKey = "jump.png";
|
||||||
|
else if (obj instanceof ILabeledNode)
|
||||||
|
imageKey = "labeled.png";
|
||||||
else if (obj instanceof IConnectorNode)
|
else if (obj instanceof IConnectorNode)
|
||||||
imageKey = "connector.png";
|
imageKey = "connector.png";
|
||||||
return ControlFlowGraphPlugin.getDefault().getImage(
|
return ControlFlowGraphPlugin.getDefault().getImage(
|
||||||
|
@ -210,26 +200,26 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param prev
|
* @param list
|
||||||
* @param startNode
|
* @param startNode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Collection<IBasicBlock> getFlat(IBasicBlock node,
|
public Collection<IBasicBlock> getFlat(IBasicBlock node,
|
||||||
Collection<IBasicBlock> prev) {
|
Collection<IBasicBlock> list) {
|
||||||
prev.add(node);
|
list.add(node);
|
||||||
if (node instanceof IConnectorNode
|
if (node instanceof IConnectorNode
|
||||||
&& !((IConnectorNode) node).hasBackwardIncoming()) {
|
&& !((IConnectorNode) node).hasBackwardIncoming() &&
|
||||||
return prev;
|
!(node instanceof ILabeledNode)) {
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
if (node instanceof IJumpNode)
|
if (node instanceof IJumpNode)
|
||||||
return prev;
|
return list;
|
||||||
if (node instanceof ISingleOutgoing) {
|
if (node instanceof ISingleOutgoing) {
|
||||||
getFlat(((ISingleOutgoing) node).getOutgoing(), prev);
|
getFlat(((ISingleOutgoing) node).getOutgoing(), list);
|
||||||
} else if (node instanceof IDecisionNode) {
|
} else if (node instanceof IDecisionNode) {
|
||||||
getFlat(((IDecisionNode) node).getConnectionNode().getOutgoing(),
|
getFlat(((IDecisionNode) node).getMergeNode().getOutgoing(), list);
|
||||||
prev);
|
|
||||||
}
|
}
|
||||||
return prev;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue