1 2 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 47 48 public class Resolver extends DefinitionTraverser { 49 50 51 private boolean mInitialized = false; 52 53 54 private LogFactory mLogFactory; 55 56 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 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 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 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 SymTabAST returnTypeNode = node.findFirstToken(TokenTypes.TYPE); 151 152 if (returnTypeNode != null) { 153 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 if (exception.getType() != TokenTypes.COMMA) { 164 resolveClass(exception, method, null, true); 165 } 166 exception = (SymTabAST) exception.getNextSibling(); 167 } 168 } 169 170 172 SymTabAST slist = node.findFirstToken(TokenTypes.SLIST); 174 175 if (slist != null) { 176 handleSList(slist, method); 177 } 178 } 179 180 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 257 private void handleAssert(BlockDef block) { 258 SymTabAST node = block.getTreeNode(); 259 260 SymTabAST conditional = 261 (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 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 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 329 private void handleFor(BlockDef block) { 330 SymTabAST node = block.getTreeNode(); 331 332 SymTabAST body; 333 SymTabAST forEach = node.findFirstToken(TokenTypes.FOR_EACH_CLAUSE); 334 if (forEach == null) { 335 SymTabAST init = node.findFirstToken(TokenTypes.FOR_INIT); 336 if (init.getFirstChild() != null) { 339 if (init.getFirstChild().getType() == TokenTypes.ELIST) { 340 resolveExpression( 341 (SymTabAST) (init.getFirstChild()), 342 block, 343 null, 344 true); 345 } 346 } 347 348 SymTabAST cond = node.findFirstToken(TokenTypes.FOR_CONDITION); 349 if (cond.getFirstChild() != null) { 350 resolveExpression( 351 (SymTabAST) (cond.getFirstChild()), 352 block, 353 null, 354 true); 355 } 356 357 SymTabAST iterator = node.findFirstToken(TokenTypes.FOR_ITERATOR); 358 if (iterator.getFirstChild() != null) { 359 resolveExpression( 360 (SymTabAST) (iterator.getFirstChild()), 361 block, 362 null, 363 true); 364 } 365 body = (SymTabAST) (iterator.getNextSibling()); 366 } 367 else { 368 resolveExpression( 369 (forEach.findFirstToken(TokenTypes.EXPR)), 370 block, 371 null, 372 true); 373 body = (SymTabAST) (forEach.getNextSibling()); 374 } 375 if (body.getType() == TokenTypes.RPAREN) { 377 body = (SymTabAST) body.getNextSibling(); 378 } 379 if (body.getType() == TokenTypes.SLIST) { 380 handleSList(body, block); 381 } 382 else { 383 resolveExpression(body, block, null, true); 384 } 385 386 } 387 388 393 private void handleIf(BlockDef block) { 394 SymTabAST node = block.getTreeNode(); 395 396 SymTabAST conditional = 397 (node.findFirstToken(TokenTypes.EXPR)); 398 resolveExpression(conditional, block, null, true); 399 400 SymTabAST body = (SymTabAST) conditional.getNextSibling(); 401 if (body.getType() == TokenTypes.RPAREN) { 403 body = (SymTabAST) body.getNextSibling(); 404 } 405 if (body != null) { 406 if (body.getType() == TokenTypes.SLIST) { 407 handleSList(body, block); 408 } 409 else { 410 resolveExpression(body, block, null, true); 411 } 412 413 SymTabAST elseBody = (SymTabAST) body.getNextSibling(); 414 while ((elseBody != null) 416 && (elseBody.getType() != TokenTypes.LITERAL_ELSE)) { 417 elseBody = (SymTabAST) elseBody.getNextSibling(); 418 } 419 426 if (elseBody != null) { 427 elseBody = (SymTabAST) elseBody.getFirstChild(); 428 } 429 if (elseBody != null) { 430 resolveExpression(elseBody, block.getParentScope(), null, true); 431 } 432 } 433 } 434 435 440 private void handleWhileAndSynchronized(BlockDef block) { 441 SymTabAST node = block.getTreeNode(); 442 443 SymTabAST condition = 444 (node.findFirstToken(TokenTypes.EXPR)); 445 SymTabAST slist = (SymTabAST) (condition.getNextSibling()); 446 if (slist.getType() == TokenTypes.RPAREN) { 448 slist = (SymTabAST) slist.getNextSibling(); 449 } 450 451 resolveExpression(condition, block, null, true); 452 handleSList(slist, block); 453 } 454 455 private void handleDoWhile(BlockDef block) { 456 SymTabAST node = block.getTreeNode(); 457 458 SymTabAST slist = (SymTabAST) node.getFirstChild(); 459 SymTabAST condition = 460 node.findFirstToken(TokenTypes.EXPR); 461 462 handleSList(slist, block); 463 resolveExpression(condition, block, null, true); 464 } 465 466 471 protected void handleVariable(VariableDef variable) { 472 SymTabAST node = variable.getTreeNode(); 473 Scope location = variable.getParentScope(); 474 475 SymTabAST nameNode = node.findFirstToken(TokenTypes.IDENT); 476 nameNode.setDefinition(variable, location, true); 477 478 SymTabAST typeNode = node.findFirstToken(TokenTypes.TYPE); 479 resolveType(typeNode, location, null, true); 480 481 SymTabAST assignmentNode = node.findFirstToken(TokenTypes.ASSIGN); 482 if (assignmentNode != null) { 483 resolveExpression( 484 (SymTabAST) (assignmentNode.getFirstChild()), 485 variable.getParentScope(), 486 null, 487 true); 488 } 489 } 490 491 496 protected void handleLabel(LabelDef label) { 497 SymTabAST node = label.getTreeNode(); 498 ((SymTabAST) node.getFirstChild()).setDefinition( 499 label, 500 label.getParentScope(), 501 true); 502 } 503 504 519 public IClass resolveExpression( 520 SymTabAST expression, 521 Scope location, 522 IClass context, 523 boolean referencePhase) { 524 IClass result = null; 525 526 try { 527 528 switch (expression.getType()) { 529 530 case TokenTypes.TYPECAST : 531 result = 532 resolveTypecast( 533 expression, 534 location, 535 context, 536 referencePhase); 537 break; 538 case TokenTypes.EXPR : 539 case TokenTypes.LITERAL_RETURN : 540 if (expression.getFirstChild() != null) { 541 result = 542 resolveExpression( 543 (SymTabAST) expression.getFirstChild(), 544 location, 545 context, 546 referencePhase); 547 } 548 else { 549 } 551 break; 552 553 case TokenTypes.ELIST : 554 555 SymTabAST child = (SymTabAST) (expression.getFirstChild()); 556 while (child != null) { 557 if (child.getType() != TokenTypes.COMMA) { 558 resolveExpression( 559 child, 560 location, 561 context, 562 referencePhase); 563 } 564 child = (SymTabAST) (child.getNextSibling()); 565 } 566 break; 567 568 case TokenTypes.IDENT : 569 result = 570 resolveIdent( 571 expression, 572 location, 573 context, 574 referencePhase); 575 break; 576 577 case TokenTypes.TYPE : 578 result = 579 resolveType( 580 expression, 581 location, 582 context, 583 referencePhase); 584 break; 585 586 case TokenTypes.METHOD_CALL : 587 result = 589 resolveMethod( 590 expression, 591 location, 592 context, 593 referencePhase); 594 break; 595 596 case TokenTypes.LITERAL_THIS : 597 result = resolveLiteralThis(expression, location, context); 598 break; 599 600 case TokenTypes.LITERAL_SUPER : 601 result = resolveLiteralSuper(expression, location, context); 602 break; 603 604 case TokenTypes.DOT : 605 result = 606 resolveDottedName( 607 expression, 608 location, 609 context, 610 referencePhase); 611 break; 612 613 case TokenTypes.LITERAL_NEW : 614 case TokenTypes.CTOR_CALL : 615 case TokenTypes.SUPER_CTOR_CALL : 616 result = 617 resolveNew( 618 expression, 619 location, 620 context, 621 referencePhase); 622 break; 623 624 case TokenTypes.LITERAL_BOOLEAN : 625 case TokenTypes.LITERAL_DOUBLE : 626 case TokenTypes.LITERAL_FLOAT : 627 case TokenTypes.LITERAL_LONG : 628 case TokenTypes.LITERAL_INT : 629 case TokenTypes.LITERAL_SHORT : 630 case TokenTypes.LITERAL_BYTE : 631 case TokenTypes.LITERAL_CHAR : 632 result = 633 resolvePrimitiveType( 634 expression, 635 location, 636 context, 637 referencePhase); 638 break; 639 640 case TokenTypes.NUM_INT : 641 case TokenTypes.NUM_LONG : 642 result = resolveNumInt(expression, location, context); 643 break; 644 645 case TokenTypes.NUM_FLOAT : 646 case TokenTypes.NUM_DOUBLE : 647 result = resolveNumFloat(expression, location, context); 648 break; 649 650 case TokenTypes.STRING_LITERAL : 651 result = 652 resolveStringLiteral(expression, location, context); 653 break; 654 655 case TokenTypes.CHAR_LITERAL : 656 result = resolveCharLiteral(expression, location, context); 657 break; 658 659 case TokenTypes.ASSIGN : 660 case TokenTypes.PLUS_ASSIGN : 661 case TokenTypes.MINUS_ASSIGN : 662 case TokenTypes.STAR_ASSIGN : 663 case TokenTypes.DIV_ASSIGN : 664 case TokenTypes.MOD_ASSIGN : 665 case TokenTypes.SR_ASSIGN : 666 case TokenTypes.BSR_ASSIGN : 667 case TokenTypes.SL_ASSIGN : 668 case TokenTypes.BAND_ASSIGN : 669 case TokenTypes.BXOR_ASSIGN : 670 case TokenTypes.BOR_ASSIGN : 671 resolveAssignment( 672 expression, 673 location, 674 context, 675 referencePhase); 676 break; 677 678 case TokenTypes.LOR : 679 case TokenTypes.LAND : 680 case TokenTypes.NOT_EQUAL : 681 case TokenTypes.EQUAL : 682 case TokenTypes.LT : 683 case TokenTypes.GT : 684 case TokenTypes.LE : 685 case TokenTypes.GE : 686 result = 687 resolveBooleanExpression( 688 expression, 689 location, 690 context, 691 referencePhase); 692 break; 693 694 case TokenTypes.LITERAL_INSTANCEOF : 695 result = 696 resolveInstanceOf( 697 expression, 698 location, 699 context, 700 referencePhase); 701 break; 702 703 case TokenTypes.LITERAL_TRUE : 704 case TokenTypes.LITERAL_FALSE : 705 result = 706 resolveBooleanLiteral(expression, location, context); 707 break; 708 709 case TokenTypes.LNOT : 710 result = 711 resolveBooleanUnary( 712 expression, 713 location, 714 context, 715 referencePhase); 716 break; 717 718 case TokenTypes.INC : 719 case TokenTypes.POST_INC : 720 case TokenTypes.DEC : 721 case TokenTypes.POST_DEC : 722 case TokenTypes.UNARY_PLUS : 723 case TokenTypes.UNARY_MINUS : 724 result = 725 resolveUnaryExpression( 726 expression, 727 location, 728 context, 729 referencePhase); 730 break; 731 732 case TokenTypes.PLUS : 733 case TokenTypes.MINUS : 734 case TokenTypes.DIV : 735 case TokenTypes.STAR : 736 case TokenTypes.BAND : 737 case TokenTypes.BOR : 738 case TokenTypes.BXOR : 739 case TokenTypes.MOD : 740 result = 741 resolveArithmeticExpression( 742 expression, 743 location, 744 context, 745 referencePhase); 746 break; 747 748 case TokenTypes.LITERAL_BREAK : 749 case TokenTypes.LITERAL_CONTINUE : 750 resolveGoto(expression, location, context, referencePhase); 751 break; 752 753 case TokenTypes.LPAREN : 754 result = resolveExpression( 755 (SymTabAST) (expression.getNextSibling()), 757 location, context, referencePhase); 759 break; 760 761 case TokenTypes.INDEX_OP : 762 result = 763 resolveArrayAccess( 764 expression, 765 location, 766 context, 767 referencePhase); 768 break; 769 770 case TokenTypes.LITERAL_NULL : 771 result = new NullClass(); 772 break; 773 774 case TokenTypes.QUESTION : 775 result = 776 resolveQuestion( 777 expression, 778 location, 779 context, 780 referencePhase); 781 break; 782 783 case TokenTypes.LITERAL_CLASS : 784 result = resolveLiteralClass(); 785 break; 786 787 case TokenTypes.ARRAY_INIT : 788 resolveArrayInitializer( 789 expression, 790 location, 791 context, 792 referencePhase); 793 break; 794 795 case TokenTypes.LITERAL_THROW : 796 resolveThrowExpression( 797 expression, 798 location, 799 context, 800 referencePhase); 801 break; 802 803 case TokenTypes.SL : 804 case TokenTypes.SR : 805 case TokenTypes.BSR : 806 result = 807 resolveShiftOperator( 808 expression, 809 location, 810 context, 811 referencePhase); 812 break; 813 814 case TokenTypes.BNOT : 815 resolveBitwiseNot( 816 expression, 817 location, 818 context, 819 referencePhase); 820 break; 821 822 case TokenTypes.LITERAL_ASSERT : 823 break; 829 830 case TokenTypes.RPAREN : 831 case TokenTypes.EMPTY_STAT : 832 case TokenTypes.VARIABLE_DEF : 835 case TokenTypes.METHOD_DEF : 836 case TokenTypes.CLASS_DEF : 837 case TokenTypes.LITERAL_FOR : 838 case TokenTypes.LITERAL_WHILE : 839 case TokenTypes.LITERAL_IF : 840 case TokenTypes.LITERAL_VOID : 841 case TokenTypes.LITERAL_DO : 843 case TokenTypes.LITERAL_SWITCH : 844 case TokenTypes.LITERAL_STATIC : 845 case TokenTypes.LITERAL_TRANSIENT : 846 case TokenTypes.LITERAL_NATIVE : 847 case TokenTypes.LITERAL_SYNCHRONIZED : 849 case TokenTypes.LITERAL_VOLATILE : 850 case TokenTypes.LITERAL_TRY : 851 case TokenTypes.LITERAL_CATCH : 852 case TokenTypes.LITERAL_FINALLY : 853 case TokenTypes.LABELED_STAT : 854 case TokenTypes.LCURLY : 855 case TokenTypes.RCURLY : 856 case TokenTypes.SLIST : 857 case TokenTypes.SEMI : 858 case TokenTypes.COMMA : 859 case TokenTypes.ARRAY_DECLARATOR : 860 break; 861 862 default : 863 if (mInitialized) { 865 final Log log = 866 mLogFactory.getInstance(this.getClass()); 867 log.error( 868 "Unhandled expression type: " 869 + expression.getType()); 870 } 871 break; 872 } 873 } 874 catch (Exception e) { 875 876 result = new UnknownClass(expression.getText(), expression); 877 } 883 884 return result; 885 } 886 887 private IClass resolveTypecast( 888 SymTabAST node, 889 Scope location, 890 IClass context, 891 boolean referencePhase) { 892 SymTabAST typeNode = (SymTabAST) node.getFirstChild(); 893 SymTabAST exprNode = (SymTabAST) typeNode.getNextSibling(); 894 if (exprNode.getType() == TokenTypes.RPAREN) { 896 exprNode = (SymTabAST) exprNode.getNextSibling(); 897 } 898 899 IClass type = null; 900 901 final SymTabAST child = (SymTabAST) typeNode.getFirstChild(); 902 final boolean createReference = false; 908 if (child.getType() 909 == TokenTypes.ARRAY_DECLARATOR) { 910 type = 911 new ArrayDef( 912 resolveType( 913 (SymTabAST) typeNode.getFirstChild(), 914 location, 915 context, 916 createReference)); 917 } 918 else { 919 type = resolveType(typeNode, location, context, createReference); 920 } 921 922 resolveExpression(exprNode, location, context, referencePhase); 923 if (type != null) { 925 ((SymTabAST) typeNode.getFirstChild()).setDefinition( 926 type, 927 location, 928 referencePhase); 929 } 930 931 return type; 932 } 933 934 private IClass resolveArrayAccess( 935 SymTabAST node, 936 Scope location, 937 IClass context, 938 boolean referencePhase) { 939 940 SymTabAST arrayNode = (SymTabAST) (node.getFirstChild()); 941 SymTabAST exprNode = (SymTabAST) (arrayNode.getNextSibling()); 942 943 while (arrayNode.getType() == TokenTypes.INDEX_OP) { 945 resolveExpression(exprNode, location, context, referencePhase); 946 arrayNode = (SymTabAST) (arrayNode.getFirstChild()); 947 exprNode = (SymTabAST) (arrayNode.getNextSibling()); 948 } 949 950 ArrayDef array = 951 (ArrayDef) resolveExpression(arrayNode, 952 location, 953 context, 954 referencePhase); 955 956 resolveExpression(exprNode, location, context, referencePhase); 957 958 return array.getType(); 959 } 960 961 private IClass resolveLiteralClass() { 962 return new ExternalClass(Class .class); 963 } 964 965 975 private IClass resolveDottedName( 976 SymTabAST tree, 977 Scope location, 978 IClass context, 979 boolean referencePhase) { 980 IClass result = null; 981 982 IClass localContext = context; 983 String name = null; 984 985 DotIterator it = new DotIterator(tree); 986 while (it.hasNext()) { 987 SymTabAST node = it.nextNode(); 988 if (node.getType() != TokenTypes.COMMA) { 989 localContext = 990 resolveExpression( 991 node, 992 location, 993 localContext, 994 referencePhase); 995 if (localContext == null) { 996 node.setMeaningfulness(false); 997 name = node.getText(); 998 while (localContext == null && it.hasNext()) { 999 SymTabAST next = it.nextNode(); 1000 name = name + "." + next.getText(); 1001 localContext = location.getClassDefinition(name); 1002 if (localContext != null && referencePhase) { 1003 next.setDefinition( 1004 localContext, 1005 location, 1006 referencePhase); 1007 } 1008 else { 1009 next.setMeaningfulness(false); 1010 } 1011 } 1012 } 1013 } 1014 } 1015 1016 if (localContext != null) { 1017 result = localContext; 1018 } 1019 else { 1020 result = new UnknownClass(name, tree); 1021 } 1022 1023 return result; 1024 } 1025 1026 1038 private IClass resolveMethod( 1039 SymTabAST methodNode, 1040 Scope location, 1041 IClass context, 1042 boolean referencePhase) { 1043 IClass result = new UnknownClass(methodNode.getText(), methodNode); 1044 IClass newContext = null; 1045 1046 if (context == null) { 1047 newContext = location.getEnclosingClass(); 1048 } 1049 else { 1050 newContext = context; 1051 } 1052 1053 String name = null; 1054 boolean createReference = true; 1055 1056 SymTabAST nameNode = (SymTabAST) (methodNode.getFirstChild()); 1057 SymTabAST parametersNode = (SymTabAST) (nameNode.getNextSibling()); 1058 1059 ISignature signature = 1060 resolveParameters( 1061 parametersNode, 1062 location, 1063 context, 1064 referencePhase); 1065 1066 if (nameNode.getType() == TokenTypes.IDENT) { 1067 name = nameNode.getText(); 1068 } 1069 else if ( 1070 nameNode.getType() == TokenTypes.LITERAL_SUPER 1071 || (nameNode.getType() == TokenTypes.SUPER_CTOR_CALL)) { 1072 IClass superclass = location.getEnclosingClass().getSuperclass(); 1073 newContext = superclass; 1074 name = superclass.getName(); 1075 createReference = false; 1076 } 1077 else if (nameNode.getType() == TokenTypes.LITERAL_THIS) { 1078 newContext = location.getEnclosingClass(); 1079 name = newContext.getName(); 1080 createReference = false; 1081 } 1082 else { 1083 SymTabAST contextNode = (SymTabAST) (nameNode.getFirstChild()); 1085 nameNode = (SymTabAST) contextNode.getNextSibling(); 1087 while (nameNode.getType() != TokenTypes.IDENT) { 1089 nameNode = (SymTabAST) nameNode.getNextSibling(); 1090 } 1091 1092 name = nameNode.getText(); 1093 newContext = 1094 resolveExpression( 1095 contextNode, 1096 location, 1097 context, 1098 referencePhase); 1099 } 1100 1101 if (newContext != null) { 1102 IMethod method = newContext.getMethodDefinition(name, signature); 1103 1104 if (method != null) { 1105 if (createReference && referencePhase) { 1106 nameNode.setDefinition(method, location, referencePhase); 1107 } 1108 result = method.getType(); 1109 } 1110 } 1111 1112 if (result == null) { 1113 result = new UnknownClass(methodNode.getText(), methodNode); 1114 } 1115 1116 return result; 1117 } 1118 1119 1129 private IClass resolveLiteralThis( 1130 SymTabAST thisNode, 1131 Scope location, 1132 IClass context) { 1133 return location.getEnclosingClass(); 1134 } 1135 1136 1146 private IClass resolveLiteralSuper( 1147 SymTabAST superNode, 1148 Scope location, 1149 IClass context) { 1150 return location.getEnclosingClass().getSuperclass(); 1151 } 1152 1153 private boolean newIsConstructor(SymTabAST newNode) { 1154 boolean result = false; 1155 1156 SymTabAST typeNode = 1157 (SymTabAST) (newNode.getFirstChild().getNextSibling()); 1158 if (typeNode.getType() == TokenTypes.LPAREN) { 1160 typeNode = (SymTabAST) typeNode.getNextSibling(); 1161 } 1162 if (typeNode.getType() == TokenTypes.ELIST) { 1163 result = true; 1164 } 1165 return result; 1166 1167 } 1168 1169 1182 public IClass resolveType( 1183 SymTabAST expr, 1184 Scope location, 1185 IClass context, 1186 boolean referencePhase) { 1187 IClass result = null; 1188 SymTabAST nameNode = (SymTabAST) expr.getFirstChild(); 1189 1190 final boolean createReference = false; 1196 if (nameNode.getType() == TokenTypes.DOT) { 1197 result = 1198 resolveDottedName(nameNode, location, context, createReference); 1199 } 1200 else { 1201 result = 1202 resolveClassIdent(nameNode, location, context, createReference); 1203 } 1204 1205 return result; 1206 } 1207 1208 1220 public IClass resolveClass( 1221 SymTabAST expr, 1222 Scope location, 1223 IClass context, 1224 boolean referencePhase) { 1225 1226 IClass result = 1227 resolveDottedName(expr, location, context, referencePhase); 1228 if (result != null && referencePhase) { 1229 expr.setDefinition(result, location, referencePhase); 1230 } 1231 1232 return result; 1233 } 1234 1235 1246 public IClass resolveClassIdent( 1247 SymTabAST expr, 1248 Scope location, 1249 IClass context, 1250 boolean referencePhase) { 1251 1252 IClass result = location.getClassDefinition(expr.getText()); 1253 if (result != null) { 1254 expr.setDefinition(result, location, referencePhase); 1255 } 1256 1257 return result; 1258 } 1259 1260 private IClass resolveNew( 1261 SymTabAST newNode, 1262 Scope location, 1263 IClass context, 1264 boolean referencePhase) { 1265 1266 IClass result; 1267 1268 if (newIsConstructor(newNode)) { 1269 result = 1270 resolveConstructor(newNode, location, context, referencePhase); 1271 } 1272 else { 1273 result = 1274 resolveNewArray(newNode, location, context, referencePhase); 1275 } 1276 1277 return result; 1278 } 1279 1280 private IClass resolveNewArray( 1281 SymTabAST newNode, 1282 Scope location, 1283 IClass context, 1284 boolean referencePhase) { 1285 IClass arrayType; 1286 1287 SymTabAST typeNode = (SymTabAST) (newNode.getFirstChild()); 1288 SymTabAST declaratorNode = (SymTabAST) (typeNode.getNextSibling()); 1289 SymTabAST initializerNode = 1290 (SymTabAST) (declaratorNode.getNextSibling()); 1291 1292 arrayType = resolveClass(typeNode, location, context, referencePhase); 1293 1294 if (declaratorNode.getFirstChild() != null) { 1295 resolveExpression( 1296 ((SymTabAST) declaratorNode.getFirstChild()), 1297 location, 1298 context, 1299 referencePhase); 1300 } 1301 1302 if (initializerNode != null) { 1303 resolveArrayInitializer( 1304 initializerNode, 1305 location, 1306 context, 1307 referencePhase); 1308 } 1309 1310 return new ArrayDef(arrayType); 1311 } 1312 1313 private IClass resolveQuestion( 1314 SymTabAST question, 1315 Scope location, 1316 IClass context, 1317 boolean referencePhase) { 1318 SymTabAST test = (SymTabAST) question.getFirstChild(); 1319 while (test.getType() == TokenTypes.LPAREN) { 1320 test = (SymTabAST) test.getNextSibling(); 1321 } 1322 SymTabAST leftBranch = (SymTabAST) test.getNextSibling(); 1323 while (leftBranch.getType() == TokenTypes.RPAREN) { 1324 leftBranch = (SymTabAST) leftBranch.getNextSibling(); 1325 } 1326 SymTabAST rightBranch = (SymTabAST) leftBranch.getNextSibling(); 1327 while (rightBranch.getType() != TokenTypes.COLON) { 1328 rightBranch = (SymTabAST) rightBranch.getNextSibling(); 1329 } 1330 rightBranch = (SymTabAST) rightBranch.getNextSibling(); 1331 1332 resolveExpression(test, location, context, referencePhase); 1333 IClass leftClass = 1334 resolveExpression(leftBranch, location, context, referencePhase); 1335 IClass rightClass = 1336 resolveExpression(rightBranch, location, context, referencePhase); 1337 1338 return moreGeneral(leftClass, rightClass); 1339 } 1340 1341 private IClass moreGeneral(IClass a, IClass b) { 1342 return (a.isCompatibleWith(b)) ? b : a; 1343 } 1344 1345 1352 private IClass resolveConstructor( 1353 SymTabAST constructor, 1354 Scope location, 1355 IClass context, 1356 boolean referencePhase) { 1357 1358 IClass classConstructed = null; 1359 1360 SymTabAST nameNode = (SymTabAST) (constructor.getFirstChild()); 1361 SymTabAST parametersNode = 1363 constructor.findFirstToken(TokenTypes.ELIST); 1364 SymTabAST nameIdent = null; 1365 if (nameNode.getType() == TokenTypes.IDENT) { 1366 nameIdent = nameNode; 1367 } 1368 else { 1369 nameIdent = (SymTabAST) nameNode.getFirstChild().getNextSibling(); 1370 } 1371 1372 classConstructed = resolveClass(nameNode, location, context, false); 1373 if (classConstructed != null) { 1374 MethodSignature signature = 1375 resolveParameters( 1376 parametersNode, 1377 location, 1378 context, 1379 referencePhase); 1380 1381 IMethod constructorDef = 1382 classConstructed.getMethodDefinition( 1383 nameIdent.getText(), 1384 signature); 1385 1386 if (constructorDef != null && referencePhase) { 1387 nameIdent.setDefinition( 1388 constructorDef, 1389 location, 1390 referencePhase); 1391 } 1392 } 1393 1394 return classConstructed; 1395 } 1396 1397 1405 private MethodSignature resolveParameters( 1406 SymTabAST elist, 1407 Scope location, 1408 IClass context, 1409 boolean referencePhase) { 1410 Vector parameters = new Vector (); 1411 1412 SymTabAST expr = (SymTabAST) (elist.getFirstChild()); 1413 while (expr != null) { 1414 if (expr.getType() != TokenTypes.COMMA) { 1415 IClass parameter = 1416 resolveExpression((SymTabAST) (expr 1417 .getFirstChild()), 1418 location, 1419 context, 1420 referencePhase); 1421 parameters.add(parameter); 1422 } 1423 1424 expr = (SymTabAST) (expr.getNextSibling()); 1425 } 1426 1427 return new MethodSignature(parameters); 1428 } 1429 1430 1438 private IClass resolveIdent( 1439 SymTabAST ident, 1440 Scope location, 1441 IClass context, 1442 boolean referencePhase) { 1443 1444 IClass result = null; 1445 IDefinition def = null; 1446 String name = ident.getText(); 1447 1448 if (context != null) { 1450 def = context.getVariableDefinition(name); 1451 } 1452 else { 1453 def = location.getVariableDefinition(name); 1454 } 1455 1456 if (def != null) { 1457 result = ((IVariable) def).getType(); 1458 } 1459 else { 1460 if (context != null) { 1462 result = context.getClassDefinition(name); 1463 } 1464 else { 1465 result = location.getClassDefinition(name); 1466 } 1467 def = result; 1468 } 1469 1470 if (def != null) { 1471 ident.setDefinition(def, location, referencePhase); 1472 } 1473 1474 return result; 1475 } 1476 1477 1486 private IClass resolveBooleanExpression( 1487 SymTabAST expression, 1488 Scope location, 1489 IClass context, 1490 boolean referencePhase) { 1491 IClass result = null; 1492 1493 SymTabAST leftChild = findLeftChild(expression); 1494 resolveExpression(leftChild, location, context, referencePhase); 1495 SymTabAST rightChild = findRightSibling(leftChild); 1496 1497 resolveExpression(rightChild, location, context, referencePhase); 1498 1499 result = LiteralResolver.getDefinition(TokenTypes.LITERAL_BOOLEAN); 1500 1501 return result; 1502 } 1503 1504 1514 private IClass resolveAssignment( 1515 SymTabAST expression, 1516 Scope location, 1517 IClass context, 1518 boolean referencePhase) { 1519 IClass result = null; 1520 1521 SymTabAST leftNode = (SymTabAST) (expression.getFirstChild()); 1522 SymTabAST rightNode = (SymTabAST) (leftNode.getNextSibling()); 1523 1524 result = resolveExpression(leftNode, location, context, referencePhase); 1525 resolveExpression(rightNode, location, context, referencePhase); 1526 1527 return result; 1528 } 1529 1530 1539 private IClass resolveUnaryExpression( 1540 SymTabAST expression, 1541 Scope location, 1542 IClass context, 1543 boolean referencePhase) { 1544 SymTabAST operatee = (SymTabAST) (expression.getFirstChild()); 1545 return resolveExpression(operatee, location, context, referencePhase); 1546 } 1547 1548 1559 private IClass resolveArithmeticExpression( 1560 SymTabAST expression, 1561 Scope location, 1562 IClass context, 1563 boolean referencePhase) { 1564 IClass result = null; 1565 1566 SymTabAST leftChild = findLeftChild(expression); 1567 1568 IClass leftType = 1569 (resolveExpression(leftChild, 1570 location, 1571 context, 1572 referencePhase)); 1573 1574 SymTabAST rightChild = findRightSibling(leftChild); 1575 1576 IClass rightType = 1577 (resolveExpression(rightChild, 1578 location, 1579 context, 1580 referencePhase)); 1581 1582 result = binaryResultType(leftType, rightType); 1583 1584 return result; 1585 } 1586 1587 1592 private SymTabAST findLeftChild(SymTabAST aExpression) { 1593 SymTabAST leftChild = (SymTabAST) (aExpression.getFirstChild()); 1594 while (leftChild.getType() == TokenTypes.LPAREN) { 1596 leftChild = (SymTabAST) leftChild.getNextSibling(); 1597 } 1598 return leftChild; 1599 } 1600 1601 1607 private SymTabAST findRightSibling(SymTabAST aLeftChild) { 1608 SymTabAST rightChild = (SymTabAST) (aLeftChild.getNextSibling()); 1609 while ((rightChild != null) 1611 && (rightChild.getType() == TokenTypes.RPAREN)) 1612 { 1613 rightChild = (SymTabAST) rightChild.getNextSibling(); 1614 } 1615 return rightChild; 1616 } 1617 1618 1627 private IClass binaryResultType(IClass a, IClass b) { 1628 1629 IClass result = null; 1630 1631 1634 IClass string = new ExternalClass(java.lang.String .class); 1635 1636 if (a.equals(string) || b.equals(string)) { 1637 result = string; 1638 } 1639 else if (a.equals(PrimitiveClasses.BOOLEAN)) { 1640 result = PrimitiveClasses.BOOLEAN; 1641 } 1642 else { 1643 result = 1644 PrimitiveClasses.binaryPromote( 1645 a, 1646 b); 1647 } 1648 1649 return result; 1650 } 1651 1652 1662 private IClass resolveInstanceOf( 1663 SymTabAST expression, 1664 Scope location, 1665 IClass context, 1666 boolean referencePhase) { 1667 SymTabAST leftNode = (SymTabAST) (expression.getFirstChild()); 1668 SymTabAST rightNode = (SymTabAST) (leftNode.getNextSibling()); 1669 1670 resolveExpression(leftNode, location, context, referencePhase); 1671 1672 SymTabAST classNameNode = (SymTabAST) (rightNode.getFirstChild()); 1673 resolveClass(classNameNode, location, context, referencePhase); 1674 1675 return LiteralResolver.getDefinition(TokenTypes.LITERAL_BOOLEAN); 1676 } 1677 1678 1688 private IClass resolveGoto( 1689 SymTabAST expression, 1690 Scope location, 1691 IClass context, 1692 boolean referencePhase) { 1693 SymTabAST label = (SymTabAST) (expression.getFirstChild()); 1694 if (label != null && (label.getType() != TokenTypes.SEMI)) { 1696 LabelDef def = location.getLabelDefinition(label.getText()); 1697 if (def != null) { 1698 label.setDefinition(def, location, referencePhase); 1699 } 1700 } 1701 1702 return null; 1703 } 1704 1705 private IClass resolvePrimitiveType( 1706 SymTabAST primitive, 1707 Scope location, 1708 IClass context, 1709 boolean referencePhase) { 1710 IClass result = 1711 LiteralResolver.getDefinition(primitive.getType()); 1712 1713 primitive.setDefinition(result, location, referencePhase); 1714 return result; 1715 } 1716 1717 1729 private IClass resolveNumInt( 1730 SymTabAST expression, 1731 Scope location, 1732 IClass context) { 1733 return PrimitiveClasses.INT; 1734 } 1735 1736 1749 private IClass resolveNumFloat( 1750 SymTabAST expression, 1751 Scope location, 1752 IClass context) { 1753 return PrimitiveClasses.DOUBLE; 1754 } 1755 1756 1766 private IClass resolveStringLiteral( 1767 SymTabAST expression, 1768 Scope location, 1769 IClass context) { 1770 return LiteralResolver.getDefinition( 1771 TokenTypes.STRING_LITERAL); 1772 } 1773 1774 1784 private IClass resolveCharLiteral( 1785 SymTabAST expression, 1786 Scope location, 1787 IClass context) { 1788 return LiteralResolver.getDefinition( 1789 TokenTypes.LITERAL_CHAR); 1790 } 1791 1792 1802 private IClass resolveBooleanLiteral( 1803 SymTabAST expression, 1804 Scope location, 1805 IClass context) { 1806 return LiteralResolver.getDefinition(TokenTypes.LITERAL_BOOLEAN); 1807 } 1808 1809 private IClass resolveBooleanUnary( 1810 SymTabAST expression, 1811 Scope location, 1812 IClass context, 1813 boolean referencePhase) { 1814 SymTabAST child = (SymTabAST) expression.getFirstChild(); 1815 resolveExpression(child, location, context, referencePhase); 1816 1817 return LiteralResolver.getDefinition(TokenTypes.LITERAL_BOOLEAN); 1818 } 1819 1820 1827 private void resolveArrayInitializer( 1828 SymTabAST initializerNode, 1829 Scope location, 1830 IClass context, 1831 boolean referencePhase) { 1832 SymTabAST child = (SymTabAST) (initializerNode.getFirstChild()); 1833 while (child != null) { 1834 if (child.getType() != TokenTypes.COMMA) { 1835 resolveExpression(child, location, context, referencePhase); 1836 } 1837 child = (SymTabAST) (child.getNextSibling()); 1838 } 1839 } 1840 1841 1848 private void resolveThrowExpression( 1849 SymTabAST throwNode, 1850 Scope location, 1851 IClass context, 1852 boolean referencePhase) { 1853 1854 SymTabAST nameNode = (SymTabAST) (throwNode.getFirstChild()); 1855 resolveExpression(nameNode, location, context, referencePhase); 1856 } 1857 1858 private IClass resolveShiftOperator( 1859 SymTabAST expression, 1860 Scope location, 1861 IClass context, 1862 boolean referencePhase) { 1863 IClass result = null; 1864 1865 SymTabAST leftChild = findLeftChild(expression); 1866 SymTabAST rightChild = findRightSibling(leftChild); 1867 1868 result = 1869 resolveExpression(leftChild, location, context, referencePhase); 1870 resolveExpression(rightChild, location, context, referencePhase); 1871 1872 result = PrimitiveClasses.unaryPromote(result); 1873 1874 return result; 1875 } 1876 1877 private IClass resolveBitwiseNot( 1878 SymTabAST expression, 1879 Scope location, 1880 IClass context, 1881 boolean referencePhase) { 1882 IClass result = null; 1883 SymTabAST child = (SymTabAST) expression.getFirstChild(); 1884 result = resolveExpression(child, location, context, referencePhase); 1885 1886 result = PrimitiveClasses.unaryPromote(result); 1887 1888 return result; 1889 } 1890} 1891 | Popular Tags |