Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/checks/usage/transmogrify/Resolver.java


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  
32  
33  import java.util.Vector;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogConfigurationException;
37  import org.apache.commons.logging.LogFactory;
38  
39  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
40  
41  /**
42   * The resolver is responsible for traversing all the various
43   * definitions in a symbol table and resolving references in them.
44   *
45   * @see SymbolTable
46   */
47  
48  public class Resolver extends DefinitionTraverser {
49  
50      /** true if the log factory has been initialized */
51      private boolean mInitialized = false;
52  
53      /** Factory for creating org.apache.commons.logging.Log instances */
54      private LogFactory mLogFactory;
55  
56      /**
57       * constructor with <code>SymbolTable</code> to be resolved
58       */
59      public Resolver(SymbolTable symbolTable) {
60          super(symbolTable);
61  
62          try {
63              mLogFactory = LogFactory.getFactory();
64          }
65          catch (LogConfigurationException e) {
66              System.out.println("log configuration exception" + e);
67          }
68          mInitialized = true;
69  
70      }
71  
72      /**
73       * resolves the symbol table
74       * @return <code>void</code>
75       * @see #traverse()
76       */
77      public void resolve() {
78          traverse();
79      }
80  
81      protected void handleSList(SymTabAST node, Scope scope) {
82          SymTabASTIterator iterator = node.getChildren();
83          while (iterator.hasNext()) {
84              SymTabAST current = iterator.nextChild();
85              resolveExpression(current, scope, null, true);
86          }
87      }
88  
89      protected void handleAnonymousInnerClass(AnonymousInnerClass innerClass) {
90          SymTabAST objblock = innerClass.getTreeNode();
91          SymTabAST expression = (SymTabAST) objblock.getFirstChild();
92          while (expression != null) {
93              resolveExpression(expression, innerClass, null, true);
94              expression = (SymTabAST) expression.getNextSibling();
95          }
96      }
97  
98      /**
99       * processes a <code>ClassDef</code> and resolves references in it
100      *
101      * @param classDef the <code>ClassDef</code> to process
102      */
103     protected void handleClass(ClassDef classDef) {
104         SymTabAST node = classDef.getTreeNode();
105 
106         if (node != null) {
107             SymTabAST nameNode = node.findFirstToken(TokenTypes.IDENT);
108             nameNode.setDefinition(classDef, classDef, true);
109 
110             SymTabAST extendsClause =
111                 node.findFirstToken(TokenTypes.EXTENDS_CLAUSE);
112             SymTabAST extendedClassNode =
113                 (SymTabAST) extendsClause.getFirstChild();
114 
115             while (extendedClassNode != null) {
116                 IClass superClass =
117                     resolveClass(extendedClassNode, classDef, null, true);
118                 extendedClassNode.setDefinition(superClass, classDef, true);
119                 extendedClassNode =
120                     (SymTabAST) extendedClassNode.getNextSibling();
121             }
122 
123             SymTabAST implementsNode =
124                 node.findFirstToken(TokenTypes.IMPLEMENTS_CLAUSE);
125 
126             if (implementsNode != null) {
127                 SymTabAST interfaceNode =
128                     (SymTabAST) (implementsNode.getFirstChild());
129                 while (interfaceNode != null) {
130                     resolveClass(interfaceNode, classDef, null, true);
131                     interfaceNode =
132                         (SymTabAST) (interfaceNode.getNextSibling());
133                 }
134             }
135         }
136     }
137 
138     /**
139      * processes a <code>MethodDef</code> and resolves references in it
140      *
141      * @param method the <code>MethodDef</code> to process
142      */
143     protected void handleMethod(MethodDef method) {
144         SymTabAST node = method.getTreeNode();
145 
146         SymTabAST nameNode = node.findFirstToken(TokenTypes.IDENT);
147         nameNode.setDefinition(method, method, true);
148 
149         // references to classes in return type
150         SymTabAST returnTypeNode = node.findFirstToken(TokenTypes.TYPE);
151 
152         if (returnTypeNode != null) {
153             // this is not a constructor
154             resolveExpression(returnTypeNode, method, null, true);
155         }
156 
157         SymTabAST throwsNode =
158             node.findFirstToken(TokenTypes.LITERAL_THROWS);
159         if (throwsNode != null) {
160             SymTabAST exception = (SymTabAST) throwsNode.getFirstChild();
161             while (exception != null) {
162                 // handle Checkstyle grammar
163                 if (exception.getType() != TokenTypes.COMMA) {
164                     resolveClass(exception, method, null, true);
165                 }
166                 exception = (SymTabAST) exception.getNextSibling();
167             }
168         }
169 
170         // references to classes in parameters
171 
172         // the body -- this would be better its own function
173         SymTabAST slist = node.findFirstToken(TokenTypes.SLIST);
174 
175         if (slist != null) {
176             handleSList(slist, method);
177         }
178     }
179 
180     /**
181      * processes a <code>BlockDef</code> and resolves references in it
182      *
183      * @param block the <code>BlockDef</code> to process
184      */
185     protected void handleBlock(BlockDef block) {
186         SymTabAST node = block.getTreeNode();
187 
188         switch (node.getType()) {
189 
190             case TokenTypes.LITERAL_FOR :
191                 handleFor(block);
192                 break;
193 
194             case TokenTypes.LITERAL_IF :
195                 handleIf(block);
196                 break;
197 
198             case TokenTypes.LITERAL_WHILE :
199                 handleWhileAndSynchronized(block);
200                 break;
201 
202             case TokenTypes.LITERAL_DO :
203                 handleDoWhile(block);
204                 break;
205 
206             case TokenTypes.LITERAL_TRY :
207             case TokenTypes.LITERAL_FINALLY :
208                 SymTabAST slist = node.findFirstToken(TokenTypes.SLIST);
209 
210                 handleSList(slist, block);
211                 break;
212 
213             case TokenTypes.LITERAL_CATCH :
214                 handleCatch(block);
215                 break;
216 
217             case TokenTypes.LITERAL_SWITCH :
218                 handleSwitch(block);
219                 break;
220 
221             case TokenTypes.SLIST :
222                 handleSList(node, block);
223                 break;
224 
225             case TokenTypes.EXPR :
226                 resolveExpression(node, block, null, true);
227                 break;
228 
229             case TokenTypes.INSTANCE_INIT :
230             case TokenTypes.STATIC_INIT :
231                 handleSList((SymTabAST) node.getFirstChild(), block);
232                 break;
233 
234             case TokenTypes.LITERAL_SYNCHRONIZED :
235                 handleWhileAndSynchronized(block);
236                 break;
237 
238             case TokenTypes.LITERAL_ASSERT :
239                 handleAssert(block);
240                 break;
241 
242             default :
243                 if (mInitialized) {
244                     final Log log = mLogFactory.getInstance(this.getClass());
245                     log.error(
246                         "Unhandled block "
247                             + block
248                             + " of type "
249                             + node.getType());
250                 }
251         }
252     }
253 
254     /**
255      * @param block
256      */
257     private void handleAssert(BlockDef block) {
258         SymTabAST node = block.getTreeNode();
259 
260         SymTabAST conditional =
261             (SymTabAST) (node.findFirstToken(TokenTypes.EXPR));
262         resolveExpression(conditional, block, null, true);
263 
264         SymTabAST message = (SymTabAST) conditional.getNextSibling();
265         while ((message != null) && (message.getType() != TokenTypes.EXPR)) {
266             message = (SymTabAST) message.getNextSibling();
267         }
268         if (message != null) {
269             resolveExpression(message, block, null, true);
270         }
271     }
272 
273     /**
274      * processes a switch statement and resolves references in it
275      *
276      * @param block the <code>BlockDef</code> to process
277      */
278     private void handleSwitch(BlockDef block) {
279         SymTabAST node = block.getTreeNode();
280 
281         SymTabAST expr = node.findFirstToken(TokenTypes.EXPR);
282         resolveExpression(expr, block, null, true);
283 
284         SymTabAST caseGroup = (SymTabAST) (expr.getNextSibling());
285         while (caseGroup != null
286             && (caseGroup.getType() != TokenTypes.CASE_GROUP)) {
287             caseGroup = (SymTabAST) caseGroup.getNextSibling();
288         }
289         if (caseGroup != null) {
290             while (caseGroup.getType() == TokenTypes.CASE_GROUP) {
291                 SymTabAST caseNode =
292                     caseGroup.findFirstToken(TokenTypes.LITERAL_CASE);
293                 while (caseNode != null
294                     && caseNode.getType() == TokenTypes.LITERAL_CASE) {
295                     resolveExpression(
296                         (SymTabAST) caseNode.getFirstChild(),
297                         block,
298                         null,
299                         true);
300                     caseNode = (SymTabAST) caseNode.getNextSibling();
301                 }
302 
303                 SymTabAST caseSlist =
304                     caseGroup.findFirstToken(TokenTypes.SLIST);
305                 handleSList(caseSlist, block);
306 
307                 caseGroup = (SymTabAST) (caseGroup.getNextSibling());
308             }
309         }
310     }
311 
312     /**
313      * processes a catch block and resolves references in it
314      *
315      * @param block the <code>BlockDef</code> to process
316      */
317     private void handleCatch(BlockDef block) {
318         SymTabAST node = block.getTreeNode();
319 
320         SymTabAST slist = node.findFirstToken(TokenTypes.SLIST);
321         handleSList(slist, block);
322     }
323 
324     /**
325      * processes a for loop and resolves references in it
326      *
327      * @param block the <code>BlockDef</code> to process
328      */
329     private void handleFor(BlockDef block) {
330         SymTabAST node = block.getTreeNode();
331 
332         SymTabAST init = node.findFirstToken(TokenTypes.FOR_INIT);
333         // only need to handle the elist case.  if the init node is a variable
334         // definition, the variable def will be handled later on in the resolution
335         if (init.getFirstChild() != null) {
336             if (init.getFirstChild().getType() == TokenTypes.ELIST) {
337                 resolveExpression(
338                     (SymTabAST) (init.getFirstChild()),
339                     block,
340                     null,
341                     true);
342             }
343         }
344 
345         SymTabAST cond = node.findFirstToken(TokenTypes.FOR_CONDITION);
346         if (cond.getFirstChild() != null) {
347             resolveExpression(
348                 (SymTabAST) (cond.getFirstChild()),
349                 block,
350                 null,
351                 true);
352         }
353 
354         SymTabAST iterator = node.findFirstToken(TokenTypes.FOR_ITERATOR);
355         if (iterator.getFirstChild() != null) {
356             resolveExpression(
357                 (SymTabAST) (iterator.getFirstChild()),
358                 block,
359                 null,
360                 true);
361         }
362 
363         //could be an SLIST, EXPR or an EMPTY_STAT
364         SymTabAST body = (SymTabAST) (iterator.getNextSibling());
365         // handle Checkstyle grammar
366         if (body.getType() == TokenTypes.RPAREN) {
367             body = (SymTabAST) body.getNextSibling();
368         }
369         if (body.getType() == TokenTypes.SLIST) {
370             handleSList(body, block);
371         }
372         else {
373             resolveExpression(body, block, null, true);
374         }
375 
376     }
377 
378     /**
379      * processes an if statement and resolves references in it
380      *
381      * @param block the <code>BlockDef</code> to process
382      */
383     private void handleIf(BlockDef block) {
384         SymTabAST node = block.getTreeNode();
385 
386         SymTabAST conditional =
387             (SymTabAST) (node.findFirstToken(TokenTypes.EXPR));
388         resolveExpression(conditional, block, null, true);
389 
390         SymTabAST body = (SymTabAST) conditional.getNextSibling();
391         // Handle Checkstyle grammar
392         if (body.getType() == TokenTypes.RPAREN) {
393             body = (SymTabAST) body.getNextSibling();
394         }
395         if (body != null && body.getType() == TokenTypes.SLIST) {
396             handleSList(body, block);
397         }
398         else {
399             resolveExpression(body, block, null, true);
400         }
401 
402         SymTabAST elseBody = (SymTabAST) body.getNextSibling();
403         //handle Checkstyle grammar
404         while ((elseBody != null)
405             && (elseBody.getType() != TokenTypes.LITERAL_ELSE)) {
406             elseBody = (SymTabAST) elseBody.getNextSibling();
407         }
408         /*
409          if (elseBody != null && elseBody.getType() == TokenTypes.SLIST) {
410              handleSList(elseBody, block);
411          }else{
412              resolveExpression(elseBody, block, null, true);
413          }
414          */
415         if (elseBody != null) {
416             elseBody = (SymTabAST) elseBody.getFirstChild();
417         }
418         if (elseBody != null) {
419             resolveExpression(elseBody, block.getParentScope(), null, true);
420         }
421     }
422 
423     /**
424      * processes a while loop and resolves references in it
425      *
426      * @param block the <code>BlockDef</code> to process
427      */
428     private void handleWhileAndSynchronized(BlockDef block) {
429         SymTabAST node = block.getTreeNode();
430 
431         SymTabAST condition =
432             (SymTabAST) (node.findFirstToken(TokenTypes.EXPR));
433         SymTabAST slist = (SymTabAST) (condition.getNextSibling());
434         // handle Checkstyle grammar
435         if (slist.getType() == TokenTypes.RPAREN) {
436             slist = (SymTabAST) slist.getNextSibling();
437         }
438 
439         resolveExpression(condition, block, null, true);
440         handleSList(slist, block);
441     }
442 
443     private void handleDoWhile(BlockDef block) {
444         SymTabAST node = block.getTreeNode();
445 
446         SymTabAST slist = (SymTabAST) node.getFirstChild();
447         SymTabAST condition =
448             (SymTabAST) node.findFirstToken(TokenTypes.EXPR);
449 
450         handleSList(slist, block);
451         resolveExpression(condition, block, null, true);
452     }
453 
454     /**
455      * processes a variable definition and resolves references in it
456      *
457      * @param variable the <code>VariableDef</code> to process
458      */
459     protected void handleVariable(VariableDef variable) {
460         SymTabAST node = variable.getTreeNode();
461         Scope location = variable.getParentScope();
462 
463         SymTabAST nameNode = node.findFirstToken(TokenTypes.IDENT);
464         nameNode.setDefinition(variable, location, true);
465 
466         SymTabAST typeNode = node.findFirstToken(TokenTypes.TYPE);
467         resolveType(typeNode, location, null, true);
468 
469         SymTabAST assignmentNode = node.findFirstToken(TokenTypes.ASSIGN);
470         if (assignmentNode != null) {
471             resolveExpression(
472                 (SymTabAST) (assignmentNode.getFirstChild()),
473                 variable.getParentScope(),
474                 null,
475                 true);
476         }
477     }
478 
479     /**
480      * processes a label and resolves references in it
481      *
482      * @param label the <code>LabelDef</code> to process
483      */
484     protected void handleLabel(LabelDef label) {
485         SymTabAST node = label.getTreeNode();
486         ((SymTabAST) node.getFirstChild()).setDefinition(
487             label,
488             label.getParentScope(),
489             true);
490     }
491 
492     /**
493      * Resolves Java expressions, returning the type to which the expression
494      * evalutes.  If this is the reference creation phase, any references found during resolution are created and
495      * resolved.
496      *
497      * @param expression the <code>SymTabAST</code> representing the expression
498      * @param location the <code>Scope</code> in which the expression occours.
499      * @param context the <code>Scope</code> in which the search for the
500      *                definition will start
501      * @param referencePhase whether or not this is the reference phase of
502      *                       table construction
503      *
504      * @return the <code>ClassDef</code> representing the type to which the
505      *         expression evalutes.
506      */
507     public IClass resolveExpression(
508         SymTabAST expression,
509         Scope location,
510         IClass context,
511         boolean referencePhase) {
512         IClass result = null;
513 
514         try {
515 
516             switch (expression.getType()) {
517 
518                 case TokenTypes.TYPECAST :
519                     result =
520                         resolveTypecast(
521                             expression,
522                             location,
523                             context,
524                             referencePhase);
525                     break;
526                 case TokenTypes.EXPR :
527                 case TokenTypes.LITERAL_RETURN :
528                     if (expression.getFirstChild() != null) {
529                         result =
530                             resolveExpression(
531                                 (SymTabAST) expression.getFirstChild(),
532                                 location,
533                                 context,
534                                 referencePhase);
535                     }
536                     else {
537                         // YOU WRITE BAD CODE!
538                     }
539                     break;
540 
541                 case TokenTypes.ELIST :
542 
543                     SymTabAST child = (SymTabAST) (expression.getFirstChild());
544                     while (child != null) {
545                         if (child.getType() != TokenTypes.COMMA) {
546                             resolveExpression(
547                                 child,
548                                 location,
549                                 context,
550                                 referencePhase);
551                         }
552                         child = (SymTabAST) (child.getNextSibling());
553                     }
554                     break;
555 
556                 case TokenTypes.IDENT :
557                     result =
558                         resolveIdent(
559                             expression,
560                             location,
561                             context,
562                             referencePhase);
563                     break;
564 
565                 case TokenTypes.TYPE :
566                     result =
567                         resolveType(
568                             expression,
569                             location,
570                             context,
571                             referencePhase);
572                     break;
573 
574                 case TokenTypes.METHOD_CALL :
575                 //case TokenTypes.SUPER_CTOR_CALL :
576                     result =
577                         resolveMethod(
578                             expression,
579                             location,
580                             context,
581                             referencePhase);
582                     break;
583 
584                 case TokenTypes.LITERAL_THIS :
585                     result = resolveLiteralThis(expression, location, context);
586                     break;
587 
588                 case TokenTypes.LITERAL_SUPER :
589                     result = resolveLiteralSuper(expression, location, context);
590                     break;
591 
592                 case TokenTypes.DOT :
593                     result =
594                         resolveDottedName(
595                             expression,
596                             location,
597                             context,
598                             referencePhase);
599                     break;
600 
601                 case TokenTypes.LITERAL_NEW :
602                 case TokenTypes.CTOR_CALL :
603                 case TokenTypes.SUPER_CTOR_CALL :
604                     result =
605                         resolveNew(
606                             expression,
607                             location,
608                             context,
609                             referencePhase);
610                     break;
611 
612                 case TokenTypes.LITERAL_BOOLEAN :
613                 case TokenTypes.LITERAL_DOUBLE :
614                 case TokenTypes.LITERAL_FLOAT :
615                 case TokenTypes.LITERAL_LONG :
616                 case TokenTypes.LITERAL_INT :
617                 case TokenTypes.LITERAL_SHORT :
618                 case TokenTypes.LITERAL_BYTE :
619                 case TokenTypes.LITERAL_CHAR :
620                     result =
621                         resolvePrimitiveType(
622                             expression,
623                             location,
624                             context,
625                             referencePhase);
626                     break;
627 
628                 case TokenTypes.NUM_INT :
629                 case TokenTypes.NUM_LONG :
630                     result = resolveNumInt(expression, location, context);
631                     break;
632 
633                 case TokenTypes.NUM_FLOAT :
634                 case TokenTypes.NUM_DOUBLE :
635                     result = resolveNumFloat(expression, location, context);
636                     break;
637 
638                 case TokenTypes.STRING_LITERAL :
639                     result =
640                         resolveStringLiteral(expression, location, context);
641                     break;
642 
643                 case TokenTypes.CHAR_LITERAL :
644                     result = resolveCharLiteral(expression, location, context);
645                     break;
646 
647                 case TokenTypes.ASSIGN :
648                 case TokenTypes.PLUS_ASSIGN :
649                 case TokenTypes.MINUS_ASSIGN :
650                 case TokenTypes.STAR_ASSIGN :
651                 case TokenTypes.DIV_ASSIGN :
652                 case TokenTypes.MOD_ASSIGN :
653                 case TokenTypes.SR_ASSIGN :
654                 case TokenTypes.BSR_ASSIGN :
655                 case TokenTypes.SL_ASSIGN :
656                 case TokenTypes.BAND_ASSIGN :
657                 case TokenTypes.BXOR_ASSIGN :
658                 case TokenTypes.BOR_ASSIGN :
659                     resolveAssignment(
660                         expression,
661                         location,
662                         context,
663                         referencePhase);
664                     break;
665 
666                 case TokenTypes.LOR :
667                 case TokenTypes.LAND :
668                 case TokenTypes.NOT_EQUAL :
669                 case TokenTypes.EQUAL :
670                 case TokenTypes.LT :
671                 case TokenTypes.GT :
672                 case TokenTypes.LE :
673                 case TokenTypes.GE :
674                     result =
675                         resolveBooleanExpression(
676                             expression,
677                             location,
678                             context,
679                             referencePhase);
680                     break;
681 
682                 case TokenTypes.LITERAL_INSTANCEOF :
683                     result =
684                         resolveInstanceOf(
685                             expression,
686                             location,
687                             context,
688                             referencePhase);
689                     break;
690 
691                 case TokenTypes.LITERAL_TRUE :
692                 case TokenTypes.LITERAL_FALSE :
693                     result =
694                         resolveBooleanLiteral(expression, location, context);
695                     break;
696 
697                 case TokenTypes.LNOT :
698                     result =
699                         resolveBooleanUnary(
700                             expression,
701                             location,
702                             context,
703                             referencePhase);
704                     break;
705 
706                 case TokenTypes.INC :
707                 case TokenTypes.POST_INC :
708                 case TokenTypes.DEC :
709                 case TokenTypes.POST_DEC :
710                 case TokenTypes.UNARY_PLUS :
711                 case TokenTypes.UNARY_MINUS :
712                     result =
713                         resolveUnaryExpression(
714                             expression,
715                             location,
716                             context,
717                             referencePhase);
718                     break;
719 
720                 case TokenTypes.PLUS :
721                 case TokenTypes.MINUS :
722                 case TokenTypes.DIV :
723                 case TokenTypes.STAR :
724                 case TokenTypes.BAND :
725                 case TokenTypes.BOR :
726                 case TokenTypes.BXOR :
727                 case TokenTypes.MOD :
728                     result =
729                         resolveArithmeticExpression(
730                             expression,
731                             location,
732                             context,
733                             referencePhase);
734                     break;
735 
736                 case TokenTypes.LITERAL_BREAK :
737                 case TokenTypes.LITERAL_CONTINUE :
738                     resolveGoto(expression, location, context, referencePhase);
739                     break;
740 
741                 case TokenTypes.LPAREN :
742                     result = resolveExpression(
743                         //TODO: child || sibling?
744      (SymTabAST) (expression.getNextSibling()),
745                         //(SymTabAST) (expression.getFirstChild()),
746     location, context, referencePhase);
747                     break;
748 
749                 case TokenTypes.INDEX_OP :
750                     result =
751                         resolveArrayAccess(
752                             expression,
753                             location,
754                             context,
755                             referencePhase);
756                     break;
757 
758                 case TokenTypes.LITERAL_NULL :
759                     result = new NullClass();
760                     break;
761 
762                 case TokenTypes.QUESTION :
763                     result =
764                         resolveQuestion(
765                             expression,
766                             location,
767                             context,
768                             referencePhase);
769                     break;
770 
771                 case TokenTypes.LITERAL_CLASS :
772                     result = resolveLiteralClass();
773                     break;
774 
775                 case TokenTypes.ARRAY_INIT :
776                     resolveArrayInitializer(
777                         expression,
778                         location,
779                         context,
780                         referencePhase);
781                     break;
782 
783                 case TokenTypes.LITERAL_THROW :
784                     resolveThrowExpression(
785                         expression,
786                         location,
787                         context,
788                         referencePhase);
789                     break;
790 
791                 case TokenTypes.SL :
792                 case TokenTypes.SR :
793                 case TokenTypes.BSR :
794                     result =
795                         resolveShiftOperator(
796                             expression,
797                             location,
798                             context,
799                             referencePhase);
800                     break;
801 
802                 case TokenTypes.BNOT :
803                     resolveBitwiseNot(
804                         expression,
805                         location,
806                         context,
807                         referencePhase);
808                     break;
809 
810                 case TokenTypes.LITERAL_ASSERT :
811 //                                        resolveAssert(
812 //                                            expression,
813 //                                            location,
814 //                                            context,
815 //                                            referencePhase);
816                     break;
817 
818                 case TokenTypes.RPAREN :
819                 case TokenTypes.EMPTY_STAT :
820                     //    case TokenTypes.ML_COMMENT:
821                     //    case TokenTypes.SL_COMMENT:
822                 case TokenTypes.VARIABLE_DEF :
823                 case TokenTypes.METHOD_DEF :
824                 case TokenTypes.CLASS_DEF :
825                 case TokenTypes.LITERAL_FOR :
826                 case TokenTypes.LITERAL_WHILE :
827                 case TokenTypes.LITERAL_IF :
828                 case TokenTypes.LITERAL_VOID :
829                     //    case TokenTypes.LITERAL_INTERFACE:
830                 case TokenTypes.LITERAL_DO :
831                 case TokenTypes.LITERAL_SWITCH :
832                 case TokenTypes.LITERAL_STATIC :
833                 case TokenTypes.LITERAL_TRANSIENT :
834                 case TokenTypes.LITERAL_NATIVE :
835                     //    case TokenTypes.LITERAL_threadsafe:
836                 case TokenTypes.LITERAL_SYNCHRONIZED :
837                 case TokenTypes.LITERAL_VOLATILE :
838                 case TokenTypes.LITERAL_TRY :
839                 case TokenTypes.LITERAL_CATCH :
840                 case TokenTypes.LITERAL_FINALLY :
841                 case TokenTypes.LABELED_STAT :
842                 case TokenTypes.LCURLY :
843                 case TokenTypes.RCURLY :
844                 case TokenTypes.SLIST :
845                 case TokenTypes.SEMI :
846                 case TokenTypes.COMMA :
847                 case TokenTypes.ARRAY_DECLARATOR :
848                     break;
849 
850                 default :
851                 //TODO: throw exception
852                     if (mInitialized) {
853                         final Log log =
854                             mLogFactory.getInstance(this.getClass());
855                         log.error(
856                             "Unhandled expression type: "
857                                 + expression.getType());
858                     }
859                     break;
860             }
861         }
862         catch (Exception e) {
863             
864             result = new UnknownClass(expression.getText(), expression);
865 //          TODO: This really should be logged
866 //            if (mInitialized) {
867 //                final Log log = mLogFactory.getInstance(this.getClass());
868 //                log.error("Error resolving near " + expression);
869 //            }
870         }
871 
872         return result;
873     }
874 
875     private IClass resolveTypecast(
876         SymTabAST node,
877         Scope location,
878         IClass context,
879         boolean referencePhase) {
880         SymTabAST typeNode = (SymTabAST) node.getFirstChild();
881         SymTabAST exprNode = (SymTabAST) typeNode.getNextSibling();
882         //handle Checkstyle grammar
883         if (exprNode.getType() == TokenTypes.RPAREN) {
884             exprNode = (SymTabAST) exprNode.getNextSibling();
885         }
886 
887         IClass type = null;
888 
889         final SymTabAST child = (SymTabAST) typeNode.getFirstChild();
890         // TODO: Checkstyle change.
891         // Do not create references from typecast.
892         // Original transmogrify code is equivalent to
893         // final boolean createReference = referencePhase;
894         // which creates non-existant references for variables.
895         final boolean createReference = false;
896         if (child.getType()
897             == TokenTypes.ARRAY_DECLARATOR) {
898             type =
899                 new ArrayDef(
900                     resolveType(
901                         (SymTabAST) typeNode.getFirstChild(),
902                         location,
903                         context,
904                         createReference));
905         }
906         else {
907             type = resolveType(typeNode, location, context, createReference);
908         }
909 
910         resolveExpression(exprNode, location, context, referencePhase);
911         //TODO: Checkstyle change. Can this be ignored?
912         if (type != null) {
913             ((SymTabAST) typeNode.getFirstChild()).setDefinition(
914                 type,
915                 location,
916                 referencePhase);
917         }
918 
919         return type;
920     }
921 
922     private IClass resolveArrayAccess(
923         SymTabAST node,
924         Scope location,
925         IClass context,
926         boolean referencePhase) {
927 
928         SymTabAST arrayNode = (SymTabAST) (node.getFirstChild());
929         SymTabAST exprNode = (SymTabAST) (arrayNode.getNextSibling());
930 
931         ArrayDef array =
932             (ArrayDef) resolveExpression(arrayNode,
933                 location,
934                 context,
935                 referencePhase);
936         resolveExpression(exprNode, location, context, referencePhase);
937 
938         return array.getType();
939     }
940 
941     private IClass resolveLiteralClass() {
942         return new ExternalClass(Class.class);
943     }
944 
945     /**
946      * Resolves any dotted reference, returning the <code>Scope</code>
947      * identified by the reference.
948      *
949      * @param tree the root node of the dotted reference
950      * @param location the <code>Scope</code> in which the expression occours.
951      * @param context the <code>Scope</code> in which the search for the
952      *                definition will start
953      * @return the <code>Scope</code> indentified by the reference
954      */
955     private IClass resolveDottedName(
956         SymTabAST tree,
957         Scope location,
958         IClass context,
959         boolean referencePhase) {
960         IClass result = null;
961 
962         IClass localContext = context;
963         String name = null;
964 
965         DotIterator it = new DotIterator(tree);
966         while (it.hasNext()) {
967             SymTabAST node = it.nextNode();
968             if (node.getType() != TokenTypes.COMMA) {
969                 localContext =
970                     resolveExpression(
971                         node,
972                         location,
973                         localContext,
974                         referencePhase);
975                 if (localContext == null) {
976                     node.setMeaningfulness(false);
977                     name = node.getText();
978                     while (localContext == null && it.hasNext()) {
979                         SymTabAST next = it.nextNode();
980                         name = name + "." + next.getText();
981                         localContext = location.getClassDefinition(name);
982                         if (localContext != null && referencePhase) {
983                             next.setDefinition(
984                                 localContext,
985                                 location,
986                                 referencePhase);
987                         }
988                         else {
989                             next.setMeaningfulness(false);
990                         }
991                     }
992                 }
993             }
994         }
995 
996         if (localContext != null) {
997             result = localContext;
998         }
999         else {
1000            result = new UnknownClass(name, tree);
1001        }
1002
1003        return result;
1004    }
1005
1006    /**
1007     * Resolves a method call.
1008     *
1009     * @param methodNode the <code>SymTabAST</code> for the METHOD_CALL node
1010     * @param location the <code>Scope</code> where the expression occurs
1011     * @param context the <code>Scope</code> in which the expression occurs
1012     *                (where the search for a defintion begins)
1013     * @param referencePhase whether or not this is the reference phase of
1014     *                       table construction
1015     *
1016     * @return the <code>ClassDef</code> for the type returned by the method
1017     */
1018    private IClass resolveMethod(
1019        SymTabAST methodNode,
1020        Scope location,
1021        IClass context,
1022        boolean referencePhase) {
1023        IClass result = new UnknownClass(methodNode.getText(), methodNode);
1024        IClass newContext = null;
1025
1026        if (context == null) {
1027            newContext = location.getEnclosingClass();
1028        }
1029        else {
1030            newContext = context;
1031        }
1032
1033        String name = null;
1034        boolean createReference = true;
1035
1036        SymTabAST nameNode = (SymTabAST) (methodNode.getFirstChild());
1037        SymTabAST parametersNode = (SymTabAST) (nameNode.getNextSibling());
1038
1039        ISignature signature =
1040            resolveParameters(
1041                parametersNode,
1042                location,
1043                context,
1044                referencePhase);
1045
1046        if (nameNode.getType() == TokenTypes.IDENT) {
1047            name = nameNode.getText();
1048        }
1049        else if (
1050            nameNode.getType() == TokenTypes.LITERAL_SUPER
1051                || (nameNode.getType() == TokenTypes.SUPER_CTOR_CALL)) {
1052            IClass superclass = location.getEnclosingClass().getSuperclass();
1053            newContext = superclass;
1054            name = superclass.getName();
1055            createReference = false;
1056        }
1057        else if (nameNode.getType() == TokenTypes.LITERAL_THIS) {
1058            newContext = location.getEnclosingClass();
1059            name = newContext.getName();
1060            createReference = false;
1061        }
1062        else {
1063            // REDTAG -- doing dotted name resolution on its own
1064            SymTabAST contextNode = (SymTabAST) (nameNode.getFirstChild());
1065            //TODO: handle Checkstyle grammar
1066            nameNode = (SymTabAST) contextNode.getNextSibling();
1067            //skip to IDENT
1068            while (nameNode.getType() != TokenTypes.IDENT) {
1069                nameNode = (SymTabAST) nameNode.getNextSibling();
1070            }
1071            
1072            name = nameNode.getText();
1073            newContext =
1074                resolveExpression(
1075                    contextNode,
1076                    location,
1077                    context,
1078                    referencePhase);
1079        }
1080
1081        if (newContext != null) {
1082            IMethod method = newContext.getMethodDefinition(name, signature);
1083
1084            if (method != null) {
1085                if (createReference && referencePhase) {
1086                    nameNode.setDefinition(method, location, referencePhase);
1087                }
1088                result = method.getType();
1089            }
1090        }
1091
1092        if (result == null) {
1093            result = new UnknownClass(methodNode.getText(), methodNode);
1094        }
1095
1096        return result;
1097    }
1098
1099    /**
1100     * resolves a literal "this"
1101     *
1102     * @param expression the <code>SymTabAST</code> of the expression
1103     * @param location the <code>Scope</code> where the expression occurs
1104     * @param context the <code>Scope</code> in which the expression occurs
1105     *                (where the search for a defintion begins)
1106     *
1107     * @return the resulting scope of the expression (the type to which it evaluates)
1108     */
1109    private IClass resolveLiteralThis(
1110        SymTabAST thisNode,
1111        Scope location,
1112        IClass context) {
1113        return location.getEnclosingClass();
1114    }
1115
1116    /**
1117     * resolves a literal "super"
1118     *
1119     * @param expression the <code>SymTabAST</code> of the expression
1120     * @param location the <code>Scope</code> where the expression occurs
1121     * @param context the <code>Scope</code> in which the expression occurs
1122     *                (where the search for a defintion begins)
1123     *
1124     * @return the resulting scope of the expression (the type to which it evaluates)
1125     */
1126    private IClass resolveLiteralSuper(
1127        SymTabAST superNode,
1128        Scope location,
1129        IClass context) {
1130        return location.getEnclosingClass().getSuperclass();
1131    }
1132
1133    private boolean newIsConstructor(SymTabAST newNode) {
1134        boolean result = false;
1135
1136        SymTabAST typeNode =
1137            (SymTabAST) (newNode.getFirstChild().getNextSibling());
1138        //handle Checkstyle grammar
1139        if (typeNode.getType() == TokenTypes.LPAREN) {
1140            typeNode = (SymTabAST) typeNode.getNextSibling();
1141        }
1142        if (typeNode.getType() == TokenTypes.ELIST) {
1143            result = true;
1144        }
1145        return result;
1146
1147    }
1148
1149    /**
1150     * resolves and expression of type TokenTypes.TYPE
1151     *
1152     * @param expression the <code>SymTabAST</code> of the expression
1153     * @param location the <code>Scope</code> where the expression occurs
1154     * @param context the <code>Scope</code> in which the expression occurs
1155     *                (where the search for a defintion begins)
1156     * @param referencePhase whether or not this is the reference phase of
1157     *                       table construction
1158     * @return the resulting scope of the expression (the type to which it evaluates)
1159     * @see #resolveDottedName(SymTabAST, Scope, IClass, boolean)
1160     * @see #resolveClassIdent(SymTabAST, Scope, IClass, boolean)
1161     */
1162    public IClass resolveType(
1163        SymTabAST expr,
1164        Scope location,
1165        IClass context,
1166        boolean referencePhase) {
1167        IClass result = null;
1168        SymTabAST nameNode = (SymTabAST) expr.getFirstChild();
1169
1170        // TODO: Checkstyle change.
1171        // Do not create references from typecast.
1172        // Original transmogrify code is equivalent to
1173        // final boolean createReference = referencePhase;
1174        // which creates non-existant references for variables.
1175        final boolean createReference = false;
1176        if (nameNode.getType() == TokenTypes.DOT) {
1177            result =
1178                resolveDottedName(nameNode, location, context, createReference);
1179        }
1180        else {
1181            result =
1182                resolveClassIdent(nameNode, location, context, createReference);
1183        }
1184
1185        return result;
1186    }
1187
1188    /**
1189     * resolves Class type expression
1190     * @param expr node to be resolved
1191     * @param location scope of the <code>expr</code>
1192     * @param context context of the <code>expr</code> if exists
1193     * @param referencePhase <code>true</code> if this method is used to during
1194     *                                         finding reference phase
1195     *                       <code>false</code> otherwise
1196     * @return <code>IClass</code> representing the type to which the
1197     *         expression evalutes.
1198     * @see #resolveDottedName(SymTabAST, Scope, IClass, boolean)
1199     */
1200    public IClass resolveClass(
1201        SymTabAST expr,
1202        Scope location,
1203        IClass context,
1204        boolean referencePhase) {
1205
1206        IClass result =
1207            resolveDottedName(expr, location, context, referencePhase);
1208        if (result != null && referencePhase) {
1209            expr.setDefinition(result, location, referencePhase);
1210        }
1211
1212        return result;
1213    }
1214
1215    /**
1216     * resolves expression with <code>JavaTokenTypes<code> other than <code>DOT</code>
1217     * @param expr expression to be resolved
1218     * @param location scope of the expression
1219     * @param context context of the expression if any
1220     * @param referencePhase <code>true</code> if this method is used to during
1221     *                                         finding reference phase
1222     *                       <code>false</c