001: package javaparser;
002:
003: import javaparser.javacc_gen.*;
004:
005: import javax.swing.tree.*;
006: import java.util.*;
007:
008: /** Used to build the syntax tree over the tokens directly from the parser in the ParserOutputProcessor.
009: *<br>
010: * Also used for the simplified tree (syntax tree displayed to the user)
011: * ( often several 10MB in memory)
012: *
013: * TODO: use a 100% NON UI treenode instead of DefaultMutableTreeNode.
014: * and create later the DefaultMutableTreeNode.
015: * => also create a pool of reusable nodes !
016: * => separate raw parser and tree representation...
017: */
018: public class ParserTreeNode extends DefaultMutableTreeNode implements
019: Comparable<ParserTreeNode> // used to sort in the view
020: {
021: // if non null, will create a list of Token
022: //boolean collectWithoutStructure = false;
023: //public ArrayList<Token> tokens = null;
024: //String prefix = "";
025: public boolean expandInView = false;
026:
027: public boolean isRawTreeRoot = false;
028:
029: // if non null, this is used as string representation
030: // for example the tree simplifier replace TypeDeclaration nodes with "public class XXX"
031: String simplifiedDescription = null;
032:
033: // if positive, defines the start line and column of this class definition
034: // set when simplifying the tree
035: private int startCol = -1, startLine = -1;
036: private int endCol = -1, endLine = -1;
037:
038: public void setStartPosFrom(Token t) {
039: startLine = t.beginLine;
040: startCol = t.beginColumn;
041: }
042:
043: public void setPositionFrom(ParserTreeNode tn) {
044: startLine = tn.startLine;
045: startCol = tn.startCol;
046:
047: endLine = tn.endLine;
048: endCol = tn.endCol;
049: }
050:
051: public void setEndPosFrom(Token t) {
052: endLine = t.endLine;
053: endCol = t.endColumn;
054: }
055:
056: public void setStart(int line, int col) {
057: startCol = col;
058: startLine = line;
059: }
060:
061: public void setEnd(int line, int col) {
062: endCol = col;
063: endLine = line;
064: }
065:
066: /** Used in the parse fro errors when one create new warning nodes and
067: wants that they have the same start and end as some target
068: */
069: public void takeBoundsFrom(ParserTreeNode n) {
070: this .startCol = n.startCol;
071: this .startLine = n.startLine;
072: this .endCol = n.endCol;
073: this .endLine = n.endLine;
074: }
075:
076: /**
077: * field 0,
078: * method 1,
079: * constructor 2
080: *
081: * enum 3
082: * class 4
083: * annotation 5 (type def)
084: * static init 6
085: */
086: protected int sortPriority = 0;
087:
088: public static volatile int created = 0;
089: public static volatile int terminated = 0;
090:
091: /** Used for compound nodes (non leafs) and parsed simplified ones.
092: * May contain a list of tokens.
093: */
094: public ParserTreeNode(String name) {
095: super (name);
096: created++;
097: }
098:
099: /** Contains a single terminal non null token (leaf)
100: (is only called during the raw tree construction).
101: */
102: public ParserTreeNode(Token t) {
103: super (t);
104: created++;
105: }
106:
107: public ParserTreeNode getChildNodeAt(int i) {
108: return (ParserTreeNode) super .getChildAt(i);
109: }
110:
111: public ParserTreeNode getParentNode() {
112: return (ParserTreeNode) this .getParent();
113: }
114:
115: public boolean isToken() {
116: return (this .getUserObject() instanceof Token);
117: }
118:
119: /** null if none
120: */
121: @edu.umd.cs.findbugs.annotations.CheckForNull
122: public Token getToken() {
123: return (Token) this .getUserObject();
124: }
125:
126: /** -1 if not a token
127: */
128: public int getTokenKind() {
129: if (!isToken())
130: return -1;
131: return getToken().kind;
132: }
133:
134: /** Used in the tree as text representation
135: */
136: @Override
137: public String toString() {
138: if (simplifiedDescription != null) {
139: return simplifiedDescription;
140: }
141:
142: return super .toString();
143: }
144:
145: public final int compareTo(ParserTreeNode n2) {
146: // [March2008]: first try to use the modifiers, first {public, package scope, protected, private}
147:
148: if (this instanceof NodeWithMod && n2 instanceof NodeWithMod) {
149: NodeWithMod nm1 = (NodeWithMod) this ;
150: NodeWithMod nm2 = (NodeWithMod) n2;
151: int cmp = Utils.compareModifiers(nm1.getModifiers(), nm2
152: .getModifiers());
153: if (cmp != 0)
154: return cmp;
155: }
156:
157: // first class then method then field, ...
158: if (sortPriority > n2.sortPriority)
159: return 1;
160: if (sortPriority < n2.sortPriority)
161: return -1;
162:
163: // alphabetic.
164: return n2.toString().compareTo(this .toString());
165: }
166:
167: public int[] getStartLinCol() {
168: int[] lc = new int[] { -1, -1 };
169: if (this .startLine > 0) {
170: lc[0] = this .startLine;
171: lc[1] = this .startCol;
172: } else if (this .isToken()) {
173: lc[0] = this .getToken().beginLine;
174: lc[1] = this .getToken().beginColumn;
175: } else {
176: // first subchild
177: Token t = Utils.getFirstSubchild(this );
178: if (t != null) {
179: lc[0] = t.beginLine;
180: lc[1] = t.beginColumn;
181: }
182: }
183: return lc;
184: }
185:
186: public int[] getEndLinCol() {
187: int[] lc = new int[] { -1, -1 };
188: if (this .endLine > 0) {
189: lc[0] = this .endLine;
190: lc[1] = this .endCol;
191: } else if (this .isToken()) {
192: lc[0] = this .getToken().endLine;
193: lc[1] = this .getToken().endColumn;
194: }
195: /* else if(this.tokens!=null && tokens.size()>0)
196: {
197: lc[0] = tokens.get(tokens.size()-1).endLine;
198: lc[1] = tokens.get(tokens.size()-1).endColumn;
199: }*/
200: else {
201: // last subchild
202: Token t = Utils.getLastSubchild(this );
203: if (t != null) {
204: lc[0] = t.endLine;
205: lc[1] = t.endColumn;
206: }
207: }
208: return lc;
209: }
210:
211: public boolean isterminated = false;
212:
213: /** Call this to help the GC !
214: * Removes itself from parent. (IMPORTANT).
215: * Overriders MUST call super.terminate()!
216: */
217: public void terminate() {
218: if (isterminated) {
219: // new Throwable().printStackTrace();
220: return;
221: }
222: isterminated = true;
223:
224: terminated++;
225: /*
226: if(terminated % 100000 ==0)
227: {
228: new Throwable().printStackTrace();
229: }*/
230:
231: removeFromParent();
232:
233: setParent(null);
234: setUserObject(null); //DEBUG
235: simplifiedDescription = null;
236: }
237:
238: }
|