01: /*
02: * Created on 11.07.2004
03: */
04: package net.sourceforge.pmd.dfa;
05:
06: import net.sourceforge.pmd.ast.SimpleNode;
07:
08: import java.util.LinkedList;
09: import java.util.List;
10: import java.util.Stack;
11:
12: /**
13: * @author raik
14: * <p/>
15: * Structure contains only raw data. A set of nodes wich represent a data flow
16: * and 2 stacks to link the nodes to each other.
17: */
18: public class Structure {
19:
20: private LinkedList<DataFlowNode> dataFlow = new LinkedList<DataFlowNode>();
21: private Stack<StackObject> braceStack = new Stack<StackObject>();
22: private Stack<StackObject> continueBreakReturnStack = new Stack<StackObject>();
23:
24: /**
25: * This class encapsulates the access to the DataFlowNode class. Is this worthwhile?
26: * TODO I think it's too confusing to have the DataFlowNode constructor
27: * add the created instance to the LinkedList. I think it'd be clearer if we did
28: * that more "procedurally", i.e., create the object, then add it to the list.
29: */
30: public IDataFlowNode createNewNode(SimpleNode node) {
31: return new DataFlowNode(node, this .dataFlow);
32: }
33:
34: public IDataFlowNode createStartNode(int line) {
35: return new StartOrEndDataFlowNode(this .dataFlow, line, true);
36: }
37:
38: public IDataFlowNode createEndNode(int line) {
39: return new StartOrEndDataFlowNode(this .dataFlow, line, false);
40: }
41:
42: public IDataFlowNode getLast() {
43: return this .dataFlow.getLast();
44: }
45:
46: public IDataFlowNode getFirst() {
47: return this .dataFlow.getFirst();
48: }
49:
50: // ----------------------------------------------------------------------------
51: // STACK FUNCTIONS
52:
53: /**
54: * The braceStack contains all nodes which are important to link the data
55: * flow nodes. The cbrStack contains continue, break, and return nodes.
56: * There are 2 Stacks because the have to process differently.
57: */
58: protected void pushOnStack(int type, IDataFlowNode node) {
59: StackObject obj = new StackObject(type, node);
60: if (type == NodeType.RETURN_STATEMENT
61: || type == NodeType.BREAK_STATEMENT
62: || type == NodeType.CONTINUE_STATEMENT
63: || type == NodeType.THROW_STATEMENT) {
64: // ugly solution - stores the type information in two ways
65: continueBreakReturnStack.push(obj);
66: } else {
67: braceStack.push(obj);
68: }
69: ((DataFlowNode) node).setType(type);
70: }
71:
72: public List getBraceStack() {
73: return braceStack;
74: }
75:
76: public List getContinueBreakReturnStack() {
77: return continueBreakReturnStack;
78: }
79:
80: }
|