1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00
This commit is contained in:
Alena Laskavaia 2010-06-01 02:24:14 +00:00
parent 544e1eecf1
commit fbd72a420b
20 changed files with 236 additions and 87 deletions

View file

@ -1,7 +1,7 @@
package org.eclipse.cdt.codan.core.model.cfg; package org.eclipse.cdt.codan.core.model.cfg;
/** /**
* Control flow graph basic block node - super interface of all nodes. * Control flow graph's basic block node - super interface of all nodes.
* It has set on incoming nodes and outgoing nodes. * It has set on incoming nodes and outgoing nodes.
* <p/> * <p/>
*/ */

View file

@ -15,9 +15,21 @@ package org.eclipse.cdt.codan.core.model.cfg;
*/ */
public interface IBranchNode extends IBasicBlock, ISingleIncoming, public interface IBranchNode extends IBasicBlock, ISingleIncoming,
ISingleOutgoing { ISingleOutgoing {
/**
* Then branch of "if" statement
*/
public static String THEN = "then"; //$NON-NLS-1$ public static String THEN = "then"; //$NON-NLS-1$
/**
* Else branch of "if" statement
*/
public static String ELSE = "else"; //$NON-NLS-1$ public static String ELSE = "else"; //$NON-NLS-1$
/**
* Default branch of "switch" statement
*/
public static String DEFAULT = "default"; //$NON-NLS-1$ public static String DEFAULT = "default"; //$NON-NLS-1$
/**
* @return label of a branch
*/
String getLabel(); String getLabel();
} }

View file

@ -18,7 +18,15 @@ package org.eclipse.cdt.codan.core.model.cfg;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICfgData { public interface ICfgData {
/**
* @return data object
*/
public abstract Object getData(); public abstract Object getData();
/**
* Sets data object for the node
*
* @param data
*/
public abstract void setData(Object data); public abstract void setData(Object data);
} }

View file

@ -1,9 +1,12 @@
package org.eclipse.cdt.codan.core.model.cfg; package org.eclipse.cdt.codan.core.model.cfg;
/** /**
* Connector node has multiple incoming branches and single outgoing * Connector node has multiple incoming branches and single outgoing.
* Incoming nodes are usually instance of {@link IJumpNode}
*/ */
public interface IConnectorNode extends IBasicBlock, ISingleOutgoing { public interface IConnectorNode extends IBasicBlock, ISingleOutgoing {
/** Backward connector has incoming node which comes from backward arcs */ /**
* @return true if one of the incoming arcs is backward arc
*/
boolean hasBackwardIncoming(); boolean hasBackwardIncoming();
} }

View file

@ -14,18 +14,53 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
/** /**
* Represents control flow graph object * Represents control flow graph (CFG) object.
* This is "normalized" control flow graph, with typed nodes:
* <br>
* <li> {@link IStartNode} - start node of the cfg (source)
* <li> {@link IExitNode} - exit node of the cfg (sink)
* <li> {@link IPlainNode} - has one incoming one outgoing
* <li> {@link IDecisionNode} - has one incoming and the only node that can have
* multiple outcoming
* arcs
* <li> {@link IConnectorNode} - the only node that can have multiple incoming
* arcs, and one outgoing
* <li> {@link IJumpNode} - has one incoming and one outgoing but represent
* change of control direction
* <li> {@link IBranchNode} - usually node where decision node connect to,
* labels represent a way where controls goes to
*/ */
public interface IControlFlowGraph { public interface IControlFlowGraph {
/**
* @return start node of the graph. CFG only has one start node.
*/
IStartNode getStartNode(); IStartNode getStartNode();
/**
* @return iterator over exit nodes of control flow graph. Exit nodes
* include return statement,
* and statements with throw and abort/exit functions.
*/
Iterator<IExitNode> getExitNodeIterator(); Iterator<IExitNode> getExitNodeIterator();
/**
* @return size of exit nodes list
*/
int getExitNodeSize(); int getExitNodeSize();
/**
* @return list of roots of dead code sections, they don't have incoming
* arcs
*/
Iterator<IBasicBlock> getUnconnectedNodeIterator(); Iterator<IBasicBlock> getUnconnectedNodeIterator();
/**
* @return size of unconnected nodes list
*/
int getUnconnectedNodeSize(); int getUnconnectedNodeSize();
/**
* @return collection of all nodes
*/
Collection<IBasicBlock> getNodes(); Collection<IBasicBlock> getNodes();
} }

View file

@ -16,5 +16,8 @@ package org.eclipse.cdt.codan.core.model.cfg;
* *
*/ */
public interface IExitNode extends IBasicBlock, ISingleIncoming { public interface IExitNode extends IBasicBlock, ISingleIncoming {
/**
* @return reference to a start node a graph
*/
IStartNode getStartNode(); IStartNode getStartNode();
} }

View file

@ -2,13 +2,19 @@ package org.eclipse.cdt.codan.core.model.cfg;
/** /**
* Node that changes the control of the graph, i.e. passes control to non-next * Node that changes the control of the graph, i.e. passes control to non-next
* statement. Can be used to implement gotos, break, continue, end of branches * statement. Can be used to implement gotos, break, continue, end of branches.
* Outgoing node is always {@link IConnectorNode}
*/ */
public interface IJumpNode extends IBasicBlock, ISingleOutgoing { public interface IJumpNode extends IBasicBlock, ISingleOutgoing {
/** /**
* True of outgoing arc is backward one * @return true of outgoing arc is backward one, see definition of backward
* arc in a "network" graph
*/ */
boolean isBackwardArc(); boolean isBackwardArc();
/**
* @return reference to a connector node to which this one "jumps" (same as
* outgoing node)
*/
IConnectorNode getJumpNode(); IConnectorNode getJumpNode();
} }

View file

@ -14,17 +14,39 @@ package org.eclipse.cdt.codan.core.model.cfg;
* Control Flow Graph Node factory * Control Flow Graph Node factory
*/ */
public interface INodeFactory { public interface INodeFactory {
/**
* @return new plain node
*/
IPlainNode createPlainNode(); IPlainNode createPlainNode();
/**
* @return new jump node
*/
IJumpNode createJumpNode(); IJumpNode createJumpNode();
/**
* @return new decision node
*/
IDecisionNode createDecisionNode(); IDecisionNode createDecisionNode();
/**
* @return new connector node
*/
IConnectorNode createConnectorNode(); IConnectorNode createConnectorNode();
/**
* @param label
* @return new branch node
*/
IBranchNode createBranchNode(String label); IBranchNode createBranchNode(String label);
/**
* @return new start node
*/
IStartNode createStartNode(); IStartNode createStartNode();
/**
* @return new exit node
*/
IExitNode createExitNode(); IExitNode createExitNode();
} }

View file

@ -1,5 +1,11 @@
package org.eclipse.cdt.codan.core.model.cfg; package org.eclipse.cdt.codan.core.model.cfg;
/**
* Node with one incoming arc
*/
public interface ISingleIncoming { public interface ISingleIncoming {
/**
* @return single incoming node
*/
IBasicBlock getIncoming(); IBasicBlock getIncoming();
} }

View file

@ -1,5 +1,11 @@
package org.eclipse.cdt.codan.core.model.cfg; package org.eclipse.cdt.codan.core.model.cfg;
/**
* Node with one outgoing arc
*/
public interface ISingleOutgoing { public interface ISingleOutgoing {
/**
* @return outgoing node
*/
IBasicBlock getOutgoing(); IBasicBlock getOutgoing();
} }

View file

@ -21,7 +21,7 @@ public interface IProblemPreferenceCompositeValue {
* Returns value of the child element of a given key * Returns value of the child element of a given key
* *
* @param key * @param key
* @return * @return value of the child preference
*/ */
Object getChildValue(String key); Object getChildValue(String key);

View file

@ -30,13 +30,37 @@ import java.util.Map;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface IProblemPreferenceDescriptor extends Cloneable { public interface IProblemPreferenceDescriptor extends Cloneable {
/**
* Type of the user preference
*/
public enum PreferenceType { public enum PreferenceType {
/**
* String type, represented by string input field by default
*/
TYPE_STRING("string"), //$NON-NLS-1$ TYPE_STRING("string"), //$NON-NLS-1$
/**
* Integer type, represented by integer input field by default
*/
TYPE_INTEGER("integer"), //$NON-NLS-1$ TYPE_INTEGER("integer"), //$NON-NLS-1$
/**
* Boolean type, represented by checkbox (boolean input field)
*/
TYPE_BOOLEAN("boolean"), //$NON-NLS-1$ TYPE_BOOLEAN("boolean"), //$NON-NLS-1$
/**
* File type, represented by file picker input field
*/
TYPE_FILE("file"), //$NON-NLS-1$ TYPE_FILE("file"), //$NON-NLS-1$
/**
* List type, represented by list (table) control
*/
TYPE_LIST("list"), //$NON-NLS-1$ TYPE_LIST("list"), //$NON-NLS-1$
/**
* Map type, represented by composite of children fields
*/
TYPE_MAP("map"), //$NON-NLS-1$ TYPE_MAP("map"), //$NON-NLS-1$
/**
* Custom type, represented by string input field by default
*/
TYPE_CUSTOM("custom"); //$NON-NLS-1$ TYPE_CUSTOM("custom"); //$NON-NLS-1$
private String literal; private String literal;
@ -44,6 +68,11 @@ public interface IProblemPreferenceDescriptor extends Cloneable {
this.literal = literal; this.literal = literal;
} }
/**
* @param name - name of the type literal (i.e. comes from name() or
* toString())
* @return type represented by this name
*/
public static PreferenceType valueOfLiteral(String name) { public static PreferenceType valueOfLiteral(String name) {
PreferenceType[] values = values(); PreferenceType[] values = values();
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@ -80,6 +109,12 @@ public interface IProblemPreferenceDescriptor extends Cloneable {
} }
} }
/**
* Key of the preference. Key must be java-like identified or number. Cannot
* contain dots. Cannot be null.
*
* @return key
*/
String getKey(); String getKey();
/** /**
@ -115,14 +150,22 @@ public interface IProblemPreferenceDescriptor extends Cloneable {
*/ */
String getToolTip(); String getToolTip();
/**
* default clone implementation
*
* @return clone of the object
*/
Object clone(); Object clone();
/**
* @return parent preference
*/
IProblemPreference getParent(); IProblemPreference getParent();
/** /**
* Combined key of values from parents plus itself separated by dot * Combined key of values from parents plus itself separated by dot
* *
* @return * @return qualified key
*/ */
String getQualifiedKey(); String getQualifiedKey();
} }

View file

@ -39,7 +39,7 @@ public interface IProblemPreferenceValue extends Cloneable {
* Export value in string representation required for storing in eclipse * Export value in string representation required for storing in eclipse
* preferences. * preferences.
* *
* @return * @return string representation of the value
*/ */
String exportValue(); String exportValue();
@ -47,8 +47,8 @@ public interface IProblemPreferenceValue extends Cloneable {
* Import value from string into internal object state. * Import value from string into internal object state.
* *
* @param str * @param str
* - string from preferences, previously exported by exportValue * - string from preferences, previously exported by exportValue
* method. * method.
*/ */
void importValue(String str); void importValue(String str);
} }

View file

@ -23,6 +23,10 @@ import java.util.Iterator;
*/ */
public class ListProblemPreference extends AbstractProblemPreference implements public class ListProblemPreference extends AbstractProblemPreference implements
IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor { IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor {
/**
* Constant that represent a key for "shared" child preference (descriptor)
* of all elements
*/
public static final String COMMON_DESCRIPTOR_KEY = "#"; //$NON-NLS-1$ public static final String COMMON_DESCRIPTOR_KEY = "#"; //$NON-NLS-1$
protected ArrayList<Object> list = new ArrayList<Object>(); protected ArrayList<Object> list = new ArrayList<Object>();
protected IProblemPreference childDescriptor; protected IProblemPreference childDescriptor;
@ -44,10 +48,10 @@ public class ListProblemPreference extends AbstractProblemPreference implements
/** /**
* Set child descriptor (all elements have the same). Value and key * Set child descriptor (all elements have the same). Value and key
* of the it would be ignored and reset. * of it would be ignored and reset.
* *
* @param desc * @param desc
* @return * @return set child descriptor
*/ */
public IProblemPreference setChildDescriptor(IProblemPreference desc) { public IProblemPreference setChildDescriptor(IProblemPreference desc) {
childDescriptor = desc; childDescriptor = desc;
@ -75,9 +79,8 @@ public class ListProblemPreference extends AbstractProblemPreference implements
} }
/** /**
* Returns descriptor of the child elements
* *
* @return * @return descriptor of the child elements
*/ */
public IProblemPreference getChildDescriptor() { public IProblemPreference getChildDescriptor() {
return childDescriptor; return childDescriptor;
@ -87,8 +90,8 @@ public class ListProblemPreference extends AbstractProblemPreference implements
* Returns cloned descriptor of the i'th child. Modifying return value would * Returns cloned descriptor of the i'th child. Modifying return value would
* not affect internal state of the list element. * not affect internal state of the list element.
* *
* @param i * @param i - index of the element
* @return * @return child preference
*/ */
public IProblemPreference getChildDescriptor(int i) { public IProblemPreference getChildDescriptor(int i) {
Object value = list.get(i); Object value = list.get(i);
@ -139,6 +142,10 @@ public class ListProblemPreference extends AbstractProblemPreference implements
return getChildValue(index); return getChildValue(index);
} }
/**
* @param index - index of the element
* @return child value by index
*/
public Object getChildValue(int index) { public Object getChildValue(int index) {
return list.get(index); return list.get(index);
} }
@ -148,6 +155,10 @@ public class ListProblemPreference extends AbstractProblemPreference implements
setChildValue(i, value); setChildValue(i, value);
} }
/**
* @param i - index of the element
* @param value - value of the child element
*/
public void setChildValue(int i, Object value) { public void setChildValue(int i, Object value) {
if (value != null) { if (value != null) {
while (i >= list.size()) { while (i >= list.size()) {
@ -161,10 +172,18 @@ public class ListProblemPreference extends AbstractProblemPreference implements
} }
} }
/**
* Adds value to the list
*
* @param value
*/
public void addChildValue(Object value) { public void addChildValue(Object value) {
list.add(value); list.add(value);
} }
/**
* Removes child value by key
*/
public void removeChildValue(String key) { public void removeChildValue(String key) {
int index = Integer.parseInt(key); int index = Integer.parseInt(key);
list.remove(index); list.remove(index);
@ -205,9 +224,6 @@ public class ListProblemPreference extends AbstractProblemPreference implements
} }
} }
/**
* @param tokenizer
*/
@Override @Override
public void importValue(StreamTokenizer tokenizer) { public void importValue(StreamTokenizer tokenizer) {
clear(); clear();
@ -243,7 +259,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
} }
/** /**
* If info key is '#' resets common descritors to null, otherwise removes * If info key is '#' resets common descriptor to null, otherwise removes
* value * value
*/ */
public void removeChildDescriptor(IProblemPreference info) { public void removeChildDescriptor(IProblemPreference info) {
@ -268,7 +284,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
} }
/** /**
* Return array of values of children elements. * @return array of values of children elements.
*/ */
@Override @Override
public Object getValue() { public Object getValue() {
@ -299,7 +315,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
} }
/** /**
* Return array of values of children elements. * @return array of values of children elements.
*/ */
public Object[] getValues() { public Object[] getValues() {
return list.toArray(new Object[list.size()]); return list.toArray(new Object[list.size()]);

View file

@ -34,6 +34,9 @@ public class MapProblemPreference extends AbstractProblemPreference implements
IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor { IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor {
protected LinkedHashMap<String, IProblemPreference> hash = new LinkedHashMap<String, IProblemPreference>(); protected LinkedHashMap<String, IProblemPreference> hash = new LinkedHashMap<String, IProblemPreference>();
/**
* Default constuctor
*/
public MapProblemPreference() { public MapProblemPreference() {
super(); super();
} }
@ -191,10 +194,16 @@ public class MapProblemPreference extends AbstractProblemPreference implements
hash.remove(info.getKey()); hash.remove(info.getKey());
} }
/**
* @return size of the map
*/
public int size() { public int size() {
return hash.size(); return hash.size();
} }
/**
* Clears the map
*/
public void clear() { public void clear() {
hash.clear(); hash.clear();
} }
@ -224,7 +233,7 @@ public class MapProblemPreference extends AbstractProblemPreference implements
* Set values for this object child elements. Elements are not present in * Set values for this object child elements. Elements are not present in
* this map would be removed. * this map would be removed.
* Preference descriptors for the keys must be set before calling this * Preference descriptors for the keys must be set before calling this
* method, unless value if instanceof IProblemPreference. * method, unless value if instanceof {@link IProblemPreference}.
* *
* @param value - must be Map<String,Object> * @param value - must be Map<String,Object>
*/ */

View file

@ -1,60 +1,42 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.ICfgData; import org.eclipse.cdt.codan.core.model.cfg.ICfgData;
/**
* Abstract Basic Block for control flow graph.
*/
public abstract class AbstractBasicBlock implements IBasicBlock, ICfgData { public abstract class AbstractBasicBlock implements IBasicBlock, ICfgData {
/**
* Empty array of basic blocks
*/
public final static IBasicBlock[] EMPTY_LIST = new IBasicBlock[0]; public final static IBasicBlock[] EMPTY_LIST = new IBasicBlock[0];
private Object data; private Object data;
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.codan.internal.core.cfg.ICfgData#getData()
*/
public Object getData() { public Object getData() {
return data; return data;
} }
/*
* (non-Javadoc)
*
* @see
* org.eclipse.cdt.codan.internal.core.cfg.ICfgData#setData(java.lang.Object
* )
*/
public void setData(Object data) { public void setData(Object data) {
this.data = data; this.data = data;
} }
static class OneElementIterator<V> implements Iterator<V> { /**
private V o; * Add a node to list of outgoing nodes of this node
*
public OneElementIterator(V o) { * @param node - node to add
this.o = o; */
}
public boolean hasNext() {
return o != null;
}
public V next() {
V x = o;
o = null;
return x;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public abstract void addOutgoing(IBasicBlock node); public abstract void addOutgoing(IBasicBlock node);
/** /**
* @return * Add a node to list of incoming nodes of this node
*
* @param node - node to add
*/
public abstract void addIncoming(IBasicBlock node);
/**
* @return toString for data object
*/ */
public String toStringData() { public String toStringData() {
if (getData() == null) if (getData() == null)
@ -66,9 +48,4 @@ public abstract class AbstractBasicBlock implements IBasicBlock, ICfgData {
public String toString() { public String toString() {
return getClass().getSimpleName() + ": " + toStringData(); //$NON-NLS-1$ return getClass().getSimpleName() + ": " + toStringData(); //$NON-NLS-1$
} }
/**
* @param node
*/
public abstract void addIncoming(IBasicBlock node);
} }

View file

@ -4,13 +4,16 @@ import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.ISingleIncoming; import org.eclipse.cdt.codan.core.model.cfg.ISingleIncoming;
/** /**
* Abstrat node with one incoming arc * Abstract node with one incoming arc (node)
* *
*/ */
public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
implements ISingleIncoming { implements ISingleIncoming {
private IBasicBlock prev; private IBasicBlock prev;
/**
* Default constructor
*/
public AbstractSingleIncomingNode() { public AbstractSingleIncomingNode() {
super(); super();
} }
@ -27,6 +30,11 @@ public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
return prev; return prev;
} }
/**
* Sets the incoming node
*
* @param prev
*/
public void setIncoming(IBasicBlock prev) { public void setIncoming(IBasicBlock prev) {
this.prev = prev; this.prev = prev;
} }

View file

@ -4,13 +4,16 @@ import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing; import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing;
/** /**
* Abstract impl of basic block with single outgoing arc * Abstract implementation of basic block with single outgoing arc (node)
* *
*/ */
public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock
implements ISingleOutgoing { implements ISingleOutgoing {
private IBasicBlock next; private IBasicBlock next;
/**
* Default constructor
*/
public AbstractSingleOutgoingNode() { public AbstractSingleOutgoingNode() {
super(); super();
} }
@ -27,20 +30,15 @@ public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock
return next; return next;
} }
public void setOutgoing(IBasicBlock exit) { /**
if (this.next != null) * Sets outgoing node
throw new IllegalArgumentException( *
"Cannot modify already exiting connector"); //$NON-NLS-1$ * @param node
this.next = exit; */
public void setOutgoing(IBasicBlock node) {
this.next = node;
} }
/*
* (non-Javadoc)
*
* @see
* org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock#addOutgoing
* (org.eclipse.cdt.codan.core.model.cfg.IBasicBlock)
*/
@Override @Override
public void addOutgoing(IBasicBlock node) { public void addOutgoing(IBasicBlock node) {
setOutgoing(node); setOutgoing(node);

View file

@ -13,7 +13,9 @@ package org.eclipse.cdt.codan.internal.core.cfg;
import org.eclipse.cdt.codan.core.model.cfg.IBranchNode; import org.eclipse.cdt.codan.core.model.cfg.IBranchNode;
/** /**
* TODO: add description * Branch node is a node with on incoming arc, one outgoing arc and a "string"
* label. Can be used to represent branches of if, switch and labelled
* statements.
*/ */
public class BranchNode extends PlainNode implements IBranchNode { public class BranchNode extends PlainNode implements IBranchNode {
protected String label; protected String label;
@ -23,11 +25,6 @@ public class BranchNode extends PlainNode implements IBranchNode {
this.label = label; this.label = label;
} }
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.codan.core.model.cfg.IBranchNode#getLabel()
*/
public String getLabel() { public String getLabel() {
return label; return label;
} }

View file

@ -27,7 +27,7 @@ import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing;
import org.eclipse.cdt.codan.core.model.cfg.IStartNode; import org.eclipse.cdt.codan.core.model.cfg.IStartNode;
/** /**
* TODO: add description * Implementation of control flow graph
*/ */
public class ControlFlowGraph implements IControlFlowGraph { public class ControlFlowGraph implements IControlFlowGraph {
private List<IExitNode> exitNodes; private List<IExitNode> exitNodes;