KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > usage > transmogrify > SymTabAST


1
2 // Transmogrify License
3
//
4
// Copyright (c) 2001, ThoughtWorks, Inc.
5
// All rights reserved.
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions
8
// are met:
9
// - Redistributions of source code must retain the above copyright notice,
10
// this list of conditions and the following disclaimer.
11
// - Redistributions in binary form must reproduce the above copyright
12
// notice, this list of conditions and the following disclaimer in the
13
// documentation and/or other materials provided with the distribution.
14
// Neither the name of the ThoughtWorks, Inc. nor the names of its
15
// contributors may be used to endorse or promote products derived from this
16
// software without specific prior written permission.
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28

29 package com.puppycrawl.tools.checkstyle.checks.usage.transmogrify;
30
31 import java.io.File JavaDoc;
32
33 import antlr.collections.AST;
34
35 import com.puppycrawl.tools.checkstyle.api.DetailAST;
36 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37
38
39
40 /**
41  * an extension of <code>antlr.CommonAST</code> that includes
42  * extra information about the AST's location. This information
43  * is the file and line number where the AST was created.
44  *
45  * To use this AST node in your tree structure, assuming your
46  * antlr.TreeParser is called parser, use
47  *
48  * parser.setASTNOdeCLass(SymTabAST.class.getName());
49  *
50  * make sure you also call setTokenObjectClass for the lexer as well
51  *
52  *
53  * @see SymTabToken
54  */

55 //TODO: Should be an adapter of DetailAST
56

57 public class SymTabAST
58     extends antlr.CommonASTWithHiddenTokens
59 {
60     private Scope _scope;
61     private IDefinition _definition = null;
62     private boolean _isMeaningful = true;
63
64     private File JavaDoc _file;
65     private int _line;
66     private int _column;
67
68 // parent is not used by Checkstyle
69
// private SymTabAST parent;
70

71     private Span _span;
72
73     /** original syntax tree node */
74     private DetailAST detailNode;
75     
76 // /**
77
// * gets parent of this node
78
// * @return <code>SymTabAST</code>
79
// */
80
// public SymTabAST getParent() {
81
// return parent;
82
// }
83

84 // /**
85
// * gets previous sibling of this node
86
// * @return <code>SymTabAST</code>
87
// */
88
// public SymTabAST getPreviousSibling() {
89
// return prevSibling;
90
// }
91

92     /**
93      * sets parent of this node
94      * @param parent
95      * @return <code>void</code>
96      */

97     public void setParent(SymTabAST parent) {
98 //parent is not used by Checkstyle
99
// this.parent = parent;
100
}
101
102     /**
103      * gets the scope of this node
104      * @return <code>Scope</code>
105      */

106     public Scope getScope() {
107         return _scope;
108     }
109
110     /**
111      * sets the scope of this node
112      * @param scope
113      * @return <code>void</code>
114      */

115     public void setScope(Scope scope) {
116         _scope = scope;
117     }
118
119     /**
120      * sets <code>Definition</code> for this node
121      * @param definition
122      * @param scope
123      * @return <code>void</code>
124      * @see #setDefinition(IDefinition, Scope, boolean)
125      */

126     public void setDefinition(IDefinition definition, Scope scope) {
127         setDefinition(definition, scope, true);
128     }
129
130     /**
131      * sets <code>Definition</code> for this node and adds <code>Reference</code>
132      * to the <code>_definition</code> and <code>scope</code>
133      * @param definition
134      * @param scope
135      * @param createReference
136      * @return <code>void</code>
137      * @see net.sourceforge.transmogrify.symtab.Reference
138      */

139     public void setDefinition(
140         IDefinition definition,
141         Scope scope,
142         boolean createReference) {
143         _definition = definition;
144         Reference reference = new Reference(this);
145         if (scope != null) {
146             scope.addReferenceInScope(reference);
147         }
148
149         if (definition.isSourced() && createReference) {
150             _definition.addReference(reference);
151         }
152     }
153
154     /**
155      * gets <code>_definitin</code>
156      * @return <code>IDefinition</code>
157      */

158     public IDefinition getDefinition() {
159         return _definition;
160     }
161
162     /**
163      * tests if this node is meaningful or should be ignored
164      * @return <code>boolean</code>
165      */

166     public boolean isMeaningful() {
167         return _isMeaningful;
168     }
169
170     /**
171      * sets <code>_isMeaningful</code> member
172      * @param isMeaningful
173      * @return <code>void</code>
174      */

175     public void setMeaningfulness(boolean isMeaningful) {
176         _isMeaningful = isMeaningful;
177     }
178
179     /**
180      * sets meaningfulness for this node and its children
181      * @return <code>void</code>
182      * @see #setMeaningfulness(boolean)
183      */

184     public void ignoreChildren() {
185         if (getType() == TokenTypes.IDENT) {
186             setMeaningfulness(false);
187         }
188         SymTabAST child = (SymTabAST) getFirstChild();
189         while (child != null) {
190             child.ignoreChildren();
191             child = (SymTabAST) child.getNextSibling();
192         }
193     }
194
195     /**
196      * sets file where this node belong to
197      * @param file
198      * @return <code>void</code>
199      */

200     public void setFile(File JavaDoc file) {
201         _file = file;
202     }
203
204     /**
205      * finishes process for adding node to its parent
206      * @param file file where this node belongs to
207      * @param parent parent of this node
208      * @param previousSibling previous sibling of this node
209      * @return <code>Span</code> the span of this node
210      * @see #setFile(File)
211      * @see #setParent(SymTabAST)
212      * @see #setPreviousSibling(SymTabAST)
213      * @see #finishChildren(File)
214      * @see #setSpan(Span)
215      */

216     public Span finishDefinition(
217         File JavaDoc file,
218         SymTabAST parent) {
219         setFile(file);
220         setParent(parent);
221
222         Span result = finishChildren(file);
223
224         if (getLineNo() != 0) {
225             result.compose(
226                 new Span(
227                     getLineNo(),
228                     getColumnNo(),
229                     getLineNo(),
230                     getColumnNo()
231                         + ((getText() == null) ? 0 : getText().length() - 1)));
232         }
233
234         setSpan(result);
235         return result;
236     }
237
238     /**
239      * finishes children of this node definition process
240      * @param file file where this node belongs to
241      * @return <code>Span</code>
242      * @see #finishDefinition(File, SymTabAST, SymTabAST)
243      */

244     public Span finishChildren(File JavaDoc file) {
245         Span result = null;
246         SymTabAST current = (SymTabAST) getFirstChild();
247
248         if (current == null) {
249             result = getSpan();
250         }
251         else {
252             while (current != null) {
253                 Span childSpan =
254                     current.finishDefinition(file, this);
255
256                 if (childSpan != null) {
257                     if (result == null) {
258                         result = new Span(childSpan);
259                     }
260                     else {
261                         result.compose(childSpan);
262                     }
263                 }
264
265                 current = (SymTabAST) current.getNextSibling();
266             }
267         }
268
269         return result;
270     }
271
272     /**
273      * gets file where this node belongs to
274      * @return <code>File</code>
275      */

276     public File JavaDoc getFile() {
277         return _file;
278     }
279
280     /**
281      * sets the line where this node reside
282      * @return <code>void</code>
283      */

284     public void setLine(int line) {
285         _line = line;
286     }
287
288     /**
289      * gets the line where this node reside
290      * @return <code>int</code>
291      */

292     public int getLineNo() {
293         return _line;
294     }
295
296     /**
297      * sets the column where this node reside
298      * @param column
299      */

300     public void setColumn(int column) {
301         _column = column;
302     }
303
304     /**
305      * gets the column where this node reside
306      * @return <code>int</code>
307      */

308     public int getColumnNo() {
309         return _column;
310     }
311
312     /**
313      * gets the definition name of this node
314      * @return <code>String</code>
315      * @see net.sourceforge.transmogrify.symtab.IDefinition
316      */

317     public String JavaDoc getName() {
318         String JavaDoc result = null;
319         if (_definition != null) {
320             result = _definition.getName();
321         }
322
323         return result;
324     }
325
326     /**
327      * prints the line, column and file for this node for debugging purpose
328      * @return <code>String</code>
329      */

330     public String JavaDoc toString() {
331         //StringBuffer resultBuffer = new StringBuffer(super.toString());
332
StringBuffer JavaDoc resultBuffer = new StringBuffer JavaDoc(prefixString(true));
333         resultBuffer.append("[" + getLineNo() + "," + getColumnNo() + "]");
334         //if ( getSpan() != null ) {
335
// resultBuffer.append( " spans " + getSpan() );
336
//}
337
resultBuffer.append(" in " + getFile());
338         //resultBuffer.append(" type: " + getType());
339
return resultBuffer.toString();
340     }
341
342     public String JavaDoc prefixString(boolean verboseStringConversion) {
343         StringBuffer JavaDoc b = new StringBuffer JavaDoc();
344
345         try {
346             final String JavaDoc name = TokenTypes.getTokenName(getType());
347             // if verbose and type name not same as text (keyword probably)
348
if (verboseStringConversion && !getText().equalsIgnoreCase(name)) {
349                 b.append('[');
350                 b.append(getText());
351                 b.append(",<");
352                 b.append(name);
353                 b.append(">]");
354                 return b.toString();
355             }
356         }
357         catch (Exception JavaDoc ex) {
358             ;
359         }
360         return getText();
361     }
362
363     /**
364      * gets <code>Span</code> of this node
365      * @return <code>Span</code>
366      */

367     public Span getSpan() {
368         if ((_span == null)) {
369             int endColumn = getColumnNo() + 1;
370             final String JavaDoc text = getText();
371             if (text != null) {
372                 endColumn += text.length() - 1;
373             }
374             _span = new Span(getLineNo(), getColumnNo() + 1, getLineNo(), endColumn);
375         }
376         return _span;
377     }
378
379     /**
380      * sets <code>Span</code> for this node
381      * @param span
382      * @return <code>void</code>
383      */

384     public void setSpan(Span span) {
385         _span = span;
386     }
387
388 // not used by Checkstyle
389
// /**
390
// * tests if this node is inside the span
391
// * @param line
392
// * @param column
393
// * @return <code>boolean</code> <code>true</code> if this node is within the span
394
// * <code>false</code> otherwise
395
// */
396
// public boolean contains(int line, int column) {
397
// return getSpan().contains(line, column);
398
// }
399

400     /**
401      * gets enclosing node for this node based on line and column
402      * @param line
403      * @param column
404      * @return <code>SymTabAST</code>
405      * @see #getSpan()
406      */

407     public SymTabAST getEnclosingNode(int line, int column) {
408         SymTabAST result = null;
409
410         if ((getSpan() != null) && (getSpan().contains(line, column))) {
411             SymTabAST child = (SymTabAST) getFirstChild();
412             while (child != null && result == null) {
413                 result = child.getEnclosingNode(line, column);
414                 child = (SymTabAST) child.getNextSibling();
415             }
416
417             // if none of the children contain it, I'm the best node
418
if (result == null) {
419                 result = this;
420             }
421
422         }
423         return result;
424     }
425
426     public AST getFirstChild()
427     {
428         if (super.getFirstChild() == null) {
429             DetailAST childDetailAST = null;
430             final DetailAST detailAST = getDetailNode();
431             if (detailAST != null) {
432                 childDetailAST = (DetailAST) detailAST.getFirstChild();
433                 if (childDetailAST != null) {
434                     final SymTabAST child =
435                         SymTabASTFactory.create(childDetailAST);
436                     setFirstChild(child);
437                     child.setParent(this);
438                     child.setFile(getFile());
439                 }
440             }
441         }
442         return super.getFirstChild();
443     }
444     
445     public AST getNextSibling()
446     {
447         if (super.getNextSibling() == null) {
448             DetailAST siblingDetailAST = null;
449             final DetailAST detailAST = getDetailNode();
450             if (detailAST != null) {
451                 siblingDetailAST = (DetailAST) detailAST.getNextSibling();
452                 if (siblingDetailAST != null) {
453                     final SymTabAST sibling =
454                     SymTabASTFactory.create(siblingDetailAST);
455                     setNextSibling(sibling);
456 // sibling.setParent(this.getParent());
457
sibling.setFile(getFile());
458                 }
459             }
460         }
461         return super.getNextSibling();
462     }
463
464     
465     /**
466      * initialized this node with input node
467      * @param aAST the node to initialize from. Must be a
468      * <code>DetailAST</code> object.
469      */

470     public void initialize(AST aAST)
471     {
472         if (aAST != null) {
473             super.initialize(aAST);
474             final DetailAST detailAST = (DetailAST) aAST;
475             setDetailNode(detailAST);
476             _column = detailAST.getColumnNo() + 1;
477             _line = detailAST.getLineNo();
478         }
479     }
480         
481     /**
482      * Gets first occurence of the child node with a certain type
483      * @param type
484      * @return <code>SymTabAST</code>
485      * @see #getType()
486      */

487     public SymTabAST findFirstToken(int type) {
488         SymTabAST result = null;
489
490         AST sibling = getFirstChild();
491         while (sibling != null) {
492             if (sibling.getType() == type) {
493                 result = (SymTabAST) sibling;
494                 break;
495             }
496             sibling = sibling.getNextSibling();
497         }
498
499         return result;
500     }
501
502 // not used by Checkstyle
503
// /**
504
// * adds a node to the last position of this node children
505
// * @param child
506
// * @return <code>void</code>
507
// */
508
// public void addChild(SymTabAST child)
509
// {
510
// SymTabAST lastChild = (SymTabAST) getFirstChild();
511
// if (lastChild == null) {
512
// setFirstChild(child);
513
// child.setParent(this);
514
// child.setNextSibling(null);
515
// }
516
// else {
517
// while (lastChild.getNextSibling() != null) {
518
// lastChild = (SymTabAST) lastChild.getNextSibling();
519
// }
520
// lastChild.setNextSibling(child);
521
// child.setNextSibling(null);
522
// child.setParent(this);
523
// }
524
// }
525

526     /**
527      * Gets Iterator for this node
528      * @return <code>SymTabASTIterator</code>
529      */

530     public SymTabASTIterator getChildren()
531     {
532         return new SymTabASTIterator(this);
533     }
534
535     /**
536      * Returns the DetailAST associated with this node.
537      * @return the DetailAST associated with this node.
538      */

539     public DetailAST getDetailNode()
540     {
541         return detailNode;
542     }
543
544     /**
545      * Sets the DetailAST associated with this node.
546      * @param aDetailAST the DetailAST associated with this node.
547      */

548     public void setDetailNode(DetailAST aDetailAST)
549     {
550         detailNode = aDetailAST;
551         ASTManager.getInstance().put(aDetailAST, this);
552     }
553
554 }
Popular Tags