1 package polyglot.ext.jl.types; 2 3 import java.lang.reflect.Modifier ; 4 import java.util.*; 5 6 import polyglot.frontend.ExtensionInfo; 7 import polyglot.frontend.Source; 8 import polyglot.main.Report; 9 import polyglot.types.*; 10 import polyglot.types.Package; 11 import polyglot.util.InternalCompilerError; 12 import polyglot.util.Position; 13 import polyglot.util.StringUtil; 14 15 21 public class TypeSystem_c implements TypeSystem 22 { 23 protected TopLevelResolver systemResolver; 24 protected TableResolver parsedResolver; 25 protected LoadedClassResolver loadedResolver; 26 protected Map flagsForName; 27 28 public TypeSystem_c() {} 29 30 34 public void initialize(LoadedClassResolver loadedResolver, ExtensionInfo extInfo) 35 throws SemanticException { 36 37 if (Report.should_report(Report.types, 1)) 38 Report.report(1, "Initializing " + getClass().getName()); 39 40 this.parsedResolver = new TableResolver(); 43 44 45 this.loadedResolver = loadedResolver; 49 50 CompoundResolver compoundResolver = 51 new CompoundResolver(parsedResolver, loadedResolver); 52 53 this.systemResolver = new CachingResolver(compoundResolver, extInfo); 58 59 initFlags(); 60 61 initTypes(); 62 } 63 64 protected void initTypes() throws SemanticException { 65 67 70 91 } 92 93 public TopLevelResolver systemResolver() { 94 return systemResolver; 95 } 96 97 public TableResolver parsedResolver() { 98 return parsedResolver; 99 } 100 101 public LoadedClassResolver loadedResolver() { 102 return loadedResolver; 103 } 104 105 public ImportTable importTable(String sourceName, Package pkg) { 106 assert_(pkg); 107 return new ImportTable(this, systemResolver, pkg, sourceName); 108 } 109 110 public ImportTable importTable(Package pkg) { 111 assert_(pkg); 112 return new ImportTable(this, systemResolver, pkg); 113 } 114 115 118 public boolean packageExists(String name) { 119 return systemResolver.packageExists(name); 120 } 121 122 protected void assert_(Collection l) { 123 for (Iterator i = l.iterator(); i.hasNext(); ) { 124 TypeObject o = (TypeObject) i.next(); 125 assert_(o); 126 } 127 } 128 129 protected void assert_(TypeObject o) { 130 if (o != null && o.typeSystem() != this) { 131 throw new InternalCompilerError("we are " + this + " but " + o + 132 " is from " + o.typeSystem()); 133 } 134 } 135 136 public String wrapperTypeString(PrimitiveType t) { 137 assert_(t); 138 139 if (t.kind() == PrimitiveType.BOOLEAN) { 140 return "java.lang.Boolean"; 141 } 142 if (t.kind() == PrimitiveType.CHAR) { 143 return "java.lang.Character"; 144 } 145 if (t.kind() == PrimitiveType.BYTE) { 146 return "java.lang.Byte"; 147 } 148 if (t.kind() == PrimitiveType.SHORT) { 149 return "java.lang.Short"; 150 } 151 if (t.kind() == PrimitiveType.INT) { 152 return "java.lang.Integer"; 153 } 154 if (t.kind() == PrimitiveType.LONG) { 155 return "java.lang.Long"; 156 } 157 if (t.kind() == PrimitiveType.FLOAT) { 158 return "java.lang.Float"; 159 } 160 if (t.kind() == PrimitiveType.DOUBLE) { 161 return "java.lang.Double"; 162 } 163 if (t.kind() == PrimitiveType.VOID) { 164 return "java.lang.Void"; 165 } 166 167 throw new InternalCompilerError("Unrecognized primitive type."); 168 } 169 170 public Context createContext() { 171 return new Context_c(this); 172 } 173 174 public Resolver packageContextResolver(Resolver cr, Package p) { 175 assert_(p); 176 return new PackageContextResolver(this, p, cr); 177 } 178 179 public Resolver classContextResolver(ClassType type) { 180 assert_(type); 181 return new ClassContextResolver(this, type); 182 } 183 184 public FieldInstance fieldInstance(Position pos, 185 ReferenceType container, Flags flags, 186 Type type, String name) { 187 assert_(container); 188 assert_(type); 189 return new FieldInstance_c(this, pos, container, flags, type, name); 190 } 191 192 public LocalInstance localInstance(Position pos, 193 Flags flags, Type type, String name) { 194 assert_(type); 195 return new LocalInstance_c(this, pos, flags, type, name); 196 } 197 198 public ConstructorInstance defaultConstructor(Position pos, 199 ClassType container) { 200 assert_(container); 201 202 Flags access = Flags.NONE; 205 if (container.flags().isPrivate()) { 206 access = access.Private(); 207 } 208 if (container.flags().isProtected()) { 209 access = access.Protected(); 210 } 211 if (container.flags().isPublic()) { 212 access = access.Public(); 213 } 214 return constructorInstance(pos, container, 215 access, Collections.EMPTY_LIST, 216 Collections.EMPTY_LIST); 217 } 218 219 public ConstructorInstance constructorInstance(Position pos, 220 ClassType container, 221 Flags flags, List argTypes, 222 List excTypes) { 223 assert_(container); 224 assert_(argTypes); 225 assert_(excTypes); 226 return new ConstructorInstance_c(this, pos, container, flags, 227 argTypes, excTypes); 228 } 229 230 public InitializerInstance initializerInstance(Position pos, 231 ClassType container, 232 Flags flags) { 233 assert_(container); 234 return new InitializerInstance_c(this, pos, container, flags); 235 } 236 237 public MethodInstance methodInstance(Position pos, 238 ReferenceType container, Flags flags, 239 Type returnType, String name, 240 List argTypes, List excTypes) { 241 242 assert_(container); 243 assert_(returnType); 244 assert_(argTypes); 245 assert_(excTypes); 246 return new MethodInstance_c(this, pos, container, flags, 247 returnType, name, argTypes, excTypes); 248 } 249 250 254 public boolean descendsFrom(Type child, Type ancestor) { 255 assert_(child); 256 assert_(ancestor); 257 return child.descendsFromImpl(ancestor); 258 } 259 260 266 public boolean isCastValid(Type fromType, Type toType) { 267 assert_(fromType); 268 assert_(toType); 269 return fromType.isCastValidImpl(toType); 270 } 271 272 283 public boolean isImplicitCastValid(Type fromType, Type toType) { 284 assert_(fromType); 285 assert_(toType); 286 return fromType.isImplicitCastValidImpl(toType); 287 } 288 289 292 public boolean equals(TypeObject type1, TypeObject type2) { 293 assert_(type1); 294 assert_(type2); 295 if (type1 instanceof TypeObject_c) { 296 return ((TypeObject_c)type1).equalsImpl(type2); 297 } else { 298 throw new InternalCompilerError("Unknown implementation of " 299 + "TypeObject", type1.position()); 300 } 301 } 302 303 307 public boolean numericConversionValid(Type t, Object value) { 308 assert_(t); 309 return t.numericConversionValidImpl(value); 310 } 311 312 317 public boolean numericConversionValid(Type t, long value) { 318 assert_(t); 319 return t.numericConversionValidImpl(value); 320 } 321 322 326 329 public boolean isCanonical(Type type) { 330 assert_(type); 331 return type.isCanonical(); 332 } 333 334 337 public boolean isAccessible(MemberInstance mi, Context context) { 338 return isAccessible(mi, context.currentClass()); 339 } 340 341 345 protected boolean isAccessible(MemberInstance mi, ClassType contextClass) { 346 assert_(mi); 347 348 ReferenceType target = mi.container(); 349 Flags flags = mi.flags(); 350 351 if (! target.isClass()) { 352 return flags.isPublic(); 355 } 356 357 ClassType targetClass = target.toClass(); 358 359 if (! classAccessible(targetClass, contextClass)) { 360 return false; 361 } 362 363 if (equals(targetClass, contextClass)) 364 return true; 365 366 if (isEnclosed(contextClass, targetClass) || isEnclosed(targetClass, contextClass)) 371 return true; 372 373 ClassType ct = contextClass; 374 while (!ct.isTopLevel()) { 375 ct = ct.outer(); 376 if (isEnclosed(targetClass, ct)) 377 return true; 378 } 379 380 if (flags.isProtected()) { 382 if (descendsFrom(contextClass, targetClass)) { 387 return true; 388 } 389 390 ct = contextClass; 391 while (!ct.isTopLevel()) { 392 ct = ct.outer(); 393 if (descendsFrom(ct, targetClass)) { 394 return true; 395 } 396 } 397 } 398 399 return accessibleFromPackage(flags, targetClass.package_(), contextClass.package_()); 400 } 401 402 403 public boolean classAccessible(ClassType targetClass, Context context) { 404 if (context.currentClass() == null) { 405 return classAccessibleFromPackage(targetClass, context.importTable().package_()); 406 } 407 else { 408 return classAccessible(targetClass, context.currentClass()); 409 } 410 } 411 412 413 protected boolean classAccessible(ClassType targetClass, ClassType contextClass) { 414 assert_(targetClass); 415 416 if (targetClass.isMember()) { 417 return isAccessible(targetClass, contextClass); 418 } 419 420 if (! targetClass.isTopLevel()) { 423 return true; 424 } 425 426 428 if (equals(targetClass, contextClass)) 430 return true; 431 432 if (isEnclosed(contextClass, targetClass)) 433 return true; 434 435 return accessibleFromPackage(targetClass.flags(), 436 targetClass.package_(), contextClass.package_()); 437 } 438 439 440 public boolean classAccessibleFromPackage(ClassType targetClass, Package pkg) { 441 assert_(targetClass); 442 443 if (! targetClass.isTopLevel() && ! targetClass.isMember()) 446 return false; 447 448 Flags flags = targetClass.flags(); 449 450 if (targetClass.isMember()) { 451 if (! targetClass.container().isClass()) { 452 return flags.isPublic(); 454 } 455 456 if (! classAccessibleFromPackage(targetClass.container().toClass(), pkg)) { 457 return false; 458 } 459 } 460 461 return accessibleFromPackage(flags, targetClass.package_(), pkg); 462 } 463 464 470 protected boolean accessibleFromPackage(Flags flags, Package pkg1, Package pkg2) { 471 if (flags.isPublic()) { 473 return true; 474 } 475 476 if (flags.isPackage() || flags.isProtected()) { 478 if (pkg1 == null && pkg2 == null) 479 return true; 480 if (pkg1 != null && pkg1.equals(pkg2)) 481 return true; 482 } 483 484 return false; 486 } 487 488 public boolean isEnclosed(ClassType inner, ClassType outer) { 489 return inner.isEnclosedImpl(outer); 490 } 491 492 public boolean hasEnclosingInstance(ClassType inner, ClassType encl) { 493 return inner.hasEnclosingInstanceImpl(encl); 494 } 495 496 public void checkCycles(ReferenceType goal) throws SemanticException { 497 checkCycles(goal, goal); 498 } 499 500 protected void checkCycles(ReferenceType curr, ReferenceType goal) 501 throws SemanticException { 502 503 assert_(curr); 504 assert_(goal); 505 506 if (curr == null) { 507 return; 508 } 509 510 ReferenceType superType = null; 511 512 if (curr.superType() != null) { 513 superType = curr.superType().toReference(); 514 } 515 516 if (goal == superType) { 517 throw new SemanticException("Circular inheritance involving " + goal, 518 curr.position()); 519 } 520 521 checkCycles(superType, goal); 522 523 for (Iterator i = curr.interfaces().iterator(); i.hasNext(); ) { 524 Type si = (Type) i.next(); 525 526 if (si == goal) { 527 throw new SemanticException("Circular inheritance involving " + goal, 528 curr.position()); 529 } 530 531 checkCycles(si.toReference(), goal); 532 } 533 if (curr.isClass()) { 534 checkCycles(curr.toClass().outer(), goal); 535 } 536 } 537 538 542 549 public boolean canCoerceToString(Type t, Context c) { 550 return ! t.isVoid(); 553 } 554 555 558 public boolean isThrowable(Type type) { 559 assert_(type); 560 return type.isThrowable(); 561 } 562 563 567 public boolean isUncheckedException(Type type) { 568 assert_(type); 569 return type.isUncheckedException(); 570 } 571 572 576 public Collection uncheckedExceptions() { 577 List l = new ArrayList(2); 578 l.add(Error()); 579 l.add(RuntimeException()); 580 return l; 581 } 582 583 public boolean isSubtype(Type t1, Type t2) { 584 assert_(t1); 585 assert_(t2); 586 return t1.isSubtypeImpl(t2); 587 } 588 589 593 596 public FieldInstance findField(ReferenceType container, String name, 597 Context c) throws SemanticException { 598 ClassType ct = null; 599 if (c != null) ct = c.currentClass(); 600 return findField(container, name, ct); 601 } 602 603 609 public FieldInstance findField(ReferenceType container, String name, 610 ClassType currClass) throws SemanticException { 611 Collection fields = findFields(container, name); 612 613 if (fields.size() == 0) { 614 throw new NoMemberException(NoMemberException.FIELD, 615 "Field \"" + name + 616 "\" not found in type \"" + 617 container + "\"."); 618 } 619 620 Iterator i = fields.iterator(); 621 FieldInstance fi = (FieldInstance) i.next(); 622 623 if (i.hasNext()) { 624 FieldInstance fi2 = (FieldInstance) i.next(); 625 626 throw new SemanticException("Field \"" + name + 627 "\" is ambiguous; it is defined in both " + 628 fi.container() + " and " + 629 fi2.container() + "."); 630 } 631 632 if (currClass != null && ! isAccessible(fi, currClass)) { 633 throw new SemanticException("Cannot access " + fi + "."); 634 } 635 636 return fi; 637 } 638 639 644 public FieldInstance findField(ReferenceType container, String name) 645 throws SemanticException { 646 647 return findField(container, name, (ClassType) null); 648 } 649 650 651 656 protected Set findFields(ReferenceType container, String name) { 657 assert_(container); 658 659 if (container == null) { 660 throw new InternalCompilerError("Cannot access field \"" + name + 661 "\" within a null container type."); 662 } 663 664 FieldInstance fi = container.fieldNamed(name); 665 666 if (fi != null) { 667 return Collections.singleton(fi); 668 } 669 670 Set fields = new HashSet(); 671 672 if (container.superType() != null && container.superType().isReference()) { 673 Set superFields = findFields(container.superType().toReference(), name); 674 fields.addAll(superFields); 675 } 676 677 if (container.isClass()) { 678 ClassType ct = container.toClass(); 680 681 for (Iterator i = ct.interfaces().iterator(); i.hasNext(); ) { 682 Type it = (Type) i.next(); 683 Set superFields = findFields(it.toReference(), name); 684 fields.addAll(superFields); 685 } 686 } 687 688 return fields; 689 } 690 691 694 public ClassType findMemberClass(ClassType container, String name, 695 Context c) throws SemanticException { 696 return findMemberClass(container, name, c.currentClass()); 697 } 698 699 public ClassType findMemberClass(ClassType container, String name, 700 ClassType currClass) throws SemanticException 701 { 702 assert_(container); 703 704 Set s = findMemberClasses(container, name); 705 706 if (s.size() == 0) { 707 throw new NoClassException(name, container); 708 } 709 710 Iterator i = s.iterator(); 711 ClassType t = (ClassType) i.next(); 712 713 if (i.hasNext()) { 714 ClassType t2 = (ClassType) i.next(); 715 throw new SemanticException("Member type \"" + name + 716 "\" is ambiguous; it is defined in both " + 717 t.container() + " and " + 718 t2.container() + "."); 719 } 720 721 if (currClass != null && ! isAccessible(t, currClass)) { 722 throw new SemanticException("Cannot access member type \"" + t + "\"."); 723 } 724 725 return t; 726 } 727 728 public Set findMemberClasses(ClassType container, String name) throws SemanticException { 729 assert_(container); 730 731 ClassType mt = container.memberClassNamed(name); 732 733 if (mt != null) { 734 if (! mt.isMember()) { 735 throw new InternalCompilerError("Class " + mt + 736 " is not a member class, " + 737 " but is in " + container + 738 "\'s list of members."); 739 } 740 741 if (mt.outer() != container) { 742 throw new InternalCompilerError("Class " + mt + 743 " has outer class " + 744 mt.outer() + 745 " but is a member of " + 746 container); 747 } 748 749 return Collections.singleton(mt); 750 } 751 752 Set memberClasses = new HashSet(); 753 754 if (container.superType() != null) { 755 Set s = findMemberClasses(container.superType().toClass(), name); 756 memberClasses.addAll(s); 757 } 758 759 for (Iterator i = container.interfaces().iterator(); i.hasNext(); ) { 760 Type it = (Type) i.next(); 761 762 Set s = findMemberClasses(it.toClass(), name); 763 memberClasses.addAll(s); 764 } 765 766 return memberClasses; 767 } 768 769 public ClassType findMemberClass(ClassType container, String name) 770 throws SemanticException { 771 772 return findMemberClass(container, name, (ClassType) null); 773 } 774 775 protected static String listToString(List l) { 776 StringBuffer sb = new StringBuffer (); 777 778 for (Iterator i = l.iterator(); i.hasNext(); ) { 779 Object o = i.next(); 780 sb.append(o.toString()); 781 782 if (i.hasNext()) { 783 sb.append(", "); 784 } 785 } 786 787 return sb.toString(); 788 } 789 790 793 public MethodInstance findMethod(ReferenceType container, 794 String name, List argTypes, Context c) 795 throws SemanticException { 796 return findMethod(container, name, argTypes, c.currentClass()); 797 } 798 799 804 public boolean hasMethodNamed(ReferenceType container, String name) { 805 assert_(container); 806 807 if (container == null) { 808 throw new InternalCompilerError("Cannot access method \"" + name + 809 "\" within a null container type."); 810 } 811 812 if (! container.methodsNamed(name).isEmpty()) { 813 return true; 814 } 815 816 if (container.superType() != null && container.superType().isReference()) { 817 if (hasMethodNamed(container.superType().toReference(), name)) { 818 return true; 819 } 820 } 821 822 if (container.isClass()) { 823 ClassType ct = container.toClass(); 824 825 for (Iterator i = ct.interfaces().iterator(); i.hasNext(); ) { 826 Type it = (Type) i.next(); 827 if (hasMethodNamed(it.toReference(), name)) { 828 return true; 829 } 830 } 831 } 832 833 return false; 834 } 835 836 843 public MethodInstance findMethod(ReferenceType container, 844 String name, List argTypes, ClassType currClass) 845 throws SemanticException { 846 847 assert_(container); 848 assert_(argTypes); 849 850 List acceptable = findAcceptableMethods(container, name, argTypes, currClass); 851 852 if (acceptable.size() == 0) { 853 throw new NoMemberException(NoMemberException.METHOD, 854 "No valid method call found for " + name + 855 "(" + listToString(argTypes) + ")" + 856 " in " + 857 container + "."); 858 } 859 860 MethodInstance mi = (MethodInstance) 861 findProcedure(acceptable, container, argTypes, currClass); 862 863 if (mi == null) { 864 throw new SemanticException("Reference to " + name + 865 " is ambiguous, multiple methods match: " 866 + acceptable); 867 } 868 869 return mi; 870 } 871 872 875 public ConstructorInstance findConstructor(ClassType container, 876 List argTypes, Context c) 877 throws SemanticException { 878 return findConstructor(container, argTypes, c.currentClass()); 879 } 880 881 public ConstructorInstance findConstructor(ClassType container, 882 List argTypes, ClassType currClass) 883 throws SemanticException { 884 885 assert_(container); 886 assert_(argTypes); 887 888 List acceptable = findAcceptableConstructors(container, argTypes, currClass); 889 890 if (acceptable.size() == 0) { 891 throw new NoMemberException(NoMemberException.CONSTRUCTOR, 892 "No valid constructor found for " + 893 container + "(" + listToString(argTypes) + ")."); 894 } 895 896 ConstructorInstance ci = (ConstructorInstance) 897 findProcedure(acceptable, container, argTypes, currClass); 898 899 if (ci == null) { 900 throw new NoMemberException(NoMemberException.CONSTRUCTOR, 901 "Reference to " + container + " is ambiguous, multiple " + 902 "constructors match: " + acceptable); 903 } 904 905 return ci; 906 } 907 908 protected ProcedureInstance findProcedure(List acceptable, 909 ReferenceType container, 910 List argTypes, 911 ClassType currClass) 912 throws SemanticException { 913 914 Collection maximal = findMostSpecificProcedures(acceptable, container, 915 argTypes, currClass); 916 917 if (maximal.size() == 1) { 918 return (ProcedureInstance) maximal.iterator().next(); 919 } 920 921 return null; 922 } 923 924 protected Collection findMostSpecificProcedures(List acceptable, 925 ReferenceType container, List argTypes, 926 ClassType currClass) 927 throws SemanticException { 928 929 assert_(container); 930 assert_(argTypes); 931 932 MostSpecificComparator msc = new MostSpecificComparator(); 935 Collections.sort(acceptable, msc); 936 937 List maximal = new ArrayList(acceptable.size()); 938 939 Iterator i = acceptable.iterator(); 940 941 ProcedureInstance first = (ProcedureInstance) i.next(); 942 maximal.add(first); 943 944 while (i.hasNext()) { 946 ProcedureInstance p = (ProcedureInstance) i.next(); 947 948 if (msc.compare(first, p) >= 0) { 949 maximal.add(p); 950 } 951 } 952 953 if (maximal.size() > 1) { 954 List notAbstract = new ArrayList(maximal.size()); 956 for (Iterator j = maximal.iterator(); j.hasNext(); ) { 957 ProcedureInstance p = (ProcedureInstance) j.next(); 958 if (! p.flags().isAbstract()) { 959 notAbstract.add(p); 960 } 961 } 962 963 if (notAbstract.size() == 1) { 964 maximal = notAbstract; 965 } 966 else if (notAbstract.size() == 0) { 967 Iterator j = maximal.iterator(); 969 first = (ProcedureInstance) j.next(); 970 while (j.hasNext()) { 971 ProcedureInstance p = (ProcedureInstance) j.next(); 972 if (! first.hasFormals(p.formalTypes())) { 973 return maximal; 975 } 976 } 977 978 maximal = Collections.singletonList(first); 980 } 981 } 982 983 return maximal; 984 } 985 986 989 protected class MostSpecificComparator implements Comparator { 990 public int compare(Object o1, Object o2) { 991 ProcedureInstance p1 = (ProcedureInstance) o1; 992 ProcedureInstance p2 = (ProcedureInstance) o2; 993 994 if (moreSpecific(p1, p2)) return -1; 995 if (moreSpecific(p2, p1)) return 1; 996 return 0; 997 } 998 } 999 1000 1004 protected List findAcceptableMethods(ReferenceType container, String name, 1005 List argTypes, ClassType currClass) 1006 throws SemanticException { 1007 1008 assert_(container); 1009 assert_(argTypes); 1010 1011 List acceptable = new ArrayList(); 1016 1017 List unacceptable = new ArrayList(); 1021 1022 Set visitedTypes = new HashSet(); 1023 1024 LinkedList typeQueue = new LinkedList(); 1025 typeQueue.addLast(container); 1026 1027 while (! typeQueue.isEmpty()) { 1028 Type type = (Type) typeQueue.removeFirst(); 1029 1030 if (visitedTypes.contains(type)) { 1031 continue; 1032 } 1033 1034 visitedTypes.add(type); 1035 1036 if (Report.should_report(Report.types, 2)) 1037 Report.report(2, "Searching type " + type + " for method " + 1038 name + "(" + listToString(argTypes) + ")"); 1039 1040 if (! type.isReference()) { 1041 throw new SemanticException("Cannot call method in " + 1042 " non-reference type " + type + "."); 1043 } 1044 1045 for (Iterator i = type.toReference().methods().iterator(); i.hasNext(); ) { 1046 MethodInstance mi = (MethodInstance) i.next(); 1047 1048 if (Report.should_report(Report.types, 3)) 1049 Report.report(3, "Trying " + mi); 1050 1051 if (methodCallValid(mi, name, argTypes)) { 1052 if (isAccessible(mi, currClass)) { 1053 if (Report.should_report(Report.types, 3)) { 1054 Report.report(3, "->acceptable: " + mi + " in " 1055 + mi.container()); 1056 } 1057 1058 acceptable.add(mi); 1059 } 1060 else { 1061 unacceptable.add(mi); 1064 } 1065 } 1066 } 1067 if (type.toReference().superType() != null) { 1068 typeQueue.addLast(type.toReference().superType()); 1069 } 1070 1071 typeQueue.addAll(type.toReference().interfaces()); 1072 } 1073 1074 for (Iterator i = unacceptable.iterator(); i.hasNext();) { 1078 MethodInstance mi = (MethodInstance)i.next(); 1079 acceptable.removeAll(mi.overrides()); 1080 } 1081 1082 return acceptable; 1083 } 1084 1085 1089 protected List findAcceptableConstructors(ClassType container, 1090 List argTypes, 1091 ClassType currClass) 1092 throws SemanticException 1093 { 1094 assert_(container); 1095 assert_(argTypes); 1096 1097 List acceptable = new ArrayList(); 1098 1099 if (Report.should_report(Report.types, 2)) 1100 Report.report(2, "Searching type " + container + 1101 " for constructor " + container + "(" + 1102 listToString(argTypes) + ")"); 1103 1104 for (Iterator i = container.constructors().iterator(); i.hasNext(); ) { 1105 ConstructorInstance ci = (ConstructorInstance) i.next(); 1106 1107 if (Report.should_report(Report.types, 3)) 1108 Report.report(3, "Trying " + ci); 1109 1110 if (callValid(ci, argTypes) && isAccessible(ci, currClass)) { 1111 if (Report.should_report(Report.types, 3)) 1112 Report.report(3, "->acceptable: " + ci); 1113 acceptable.add(ci); 1114 } 1115 } 1116 1117 return acceptable; 1118 } 1119 1120 1124 public boolean moreSpecific(ProcedureInstance p1, ProcedureInstance p2) { 1125 return p1.moreSpecificImpl(p2); 1126 } 1127 1128 1131 public Type superType(ReferenceType type) { 1132 assert_(type); 1133 return type.superType(); 1134 } 1135 1136 1140 public List interfaces(ReferenceType type) { 1141 assert_(type); 1142 return type.interfaces(); 1143 } 1144 1145 1149 public Type leastCommonAncestor(Type type1, Type type2) 1150 throws SemanticException 1151 { 1152 assert_(type1); 1153 assert_(type2); 1154 1155 if (equals(type1, type2)) return type1; 1156 1157 if (type1.isNumeric() && type2.isNumeric()) { 1158 if (isImplicitCastValid(type1, type2)) { 1159 return type2; 1160 } 1161 1162 if (isImplicitCastValid(type2, type1)) { 1163 return type1; 1164 } 1165 1166 if (type1.isChar() && type2.isByte() || 1167 type1.isByte() && type2.isChar()) { 1168 return Int(); 1169 } 1170 1171 if (type1.isChar() && type2.isShort() || 1172 type1.isShort() && type2.isChar()) { 1173 return Int(); 1174 } 1175 } 1176 1177 if (type1.isArray() && type2.isArray()) { 1178 return arrayOf(leastCommonAncestor(type1.toArray().base(), 1179 type2.toArray().base())); 1180 } 1181 1182 if (type1.isReference() && type2.isNull()) return type1; 1183 if (type2.isReference() && type1.isNull()) return type2; 1184 1185 if (type1.isReference() && type2.isReference()) { 1186 if (type1.isClass() && type1.toClass().flags().isInterface()) { 1188 return Object(); 1189 } 1190 1191 if (type2.isClass() && type2.toClass().flags().isInterface()) { 1192 return Object(); 1193 } 1194 1195 if (equals(type1, Object())) return type1; 1197 if (equals(type2, Object())) return type2; 1198 1199 if (isSubtype(type1, type2)) return type2; 1200 if (isSubtype(type2, type1)) return type1; 1201 1202 Type t1 = leastCommonAncestor(type1.toReference().superType(), 1204 type2); 1205 Type t2 = leastCommonAncestor(type2.toReference().superType(), 1206 type1); 1207 1208 if (equals(t1, t2)) return t1; 1209 1210 return Object(); 1211 } 1212 1213 throw new SemanticException( 1214 "No least common ancestor found for types \"" + type1 + 1215 "\" and \"" + type2 + "\"."); 1216 } 1217 1218 1222 1225 public boolean throwsSubset(ProcedureInstance p1, ProcedureInstance p2) { 1226 assert_(p1); 1227 assert_(p2); 1228 return p1.throwsSubsetImpl(p2); 1229 } 1230 1231 1232 public boolean hasFormals(ProcedureInstance pi, List formalTypes) { 1233 assert_(pi); 1234 assert_(formalTypes); 1235 return pi.hasFormalsImpl(formalTypes); 1236 } 1237 1238 1239 public boolean hasMethod(ReferenceType t, MethodInstance mi) { 1240 assert_(t); 1241 assert_(mi); 1242 return t.hasMethodImpl(mi); 1243 } 1244 1245 public List overrides(MethodInstance mi) { 1246 return mi.overridesImpl(); 1247 } 1248 1249 public List implemented(MethodInstance mi) { 1250 return mi.implementedImpl(mi.container()); 1251 } 1252 1253 public boolean canOverride(MethodInstance mi, MethodInstance mj) { 1254 try { 1255 return mi.canOverrideImpl(mj, true); 1256 } 1257 catch (SemanticException e) { 1258 throw new InternalCompilerError(e); 1262 } 1263 } 1264 1265 public void checkOverride(MethodInstance mi, MethodInstance mj) throws SemanticException { 1266 mi.canOverrideImpl(mj, false); 1267 } 1268 1269 1272 public boolean isSameMethod(MethodInstance m1, MethodInstance m2) { 1273 assert_(m1); 1274 assert_(m2); 1275 return m1.isSameMethodImpl(m2); 1276 } 1277 1278 public boolean methodCallValid(MethodInstance prototype, 1279 String name, List argTypes) { 1280 assert_(prototype); 1281 assert_(argTypes); 1282 return prototype.methodCallValidImpl(name, argTypes); 1283 } 1284 1285 public boolean callValid(ProcedureInstance prototype, List argTypes) { 1286 assert_(prototype); 1287 assert_(argTypes); 1288 return prototype.callValidImpl(argTypes); 1289 } 1290 1291 public NullType Null() { return NULL_; } 1295 public PrimitiveType Void() { return VOID_; } 1296 public PrimitiveType Boolean() { return BOOLEAN_; } 1297 public PrimitiveType Char() { return CHAR_; } 1298 public PrimitiveType Byte() { return BYTE_; } 1299 public PrimitiveType Short() { return SHORT_; } 1300 public PrimitiveType Int() { return INT_; } 1301 public PrimitiveType Long() { return LONG_; } 1302 public PrimitiveType Float() { return FLOAT_; } 1303 public PrimitiveType Double() { return DOUBLE_; } 1304 1305 protected ClassType load(String name) { 1306 try { 1307 return (ClassType) typeForName(name); 1308 } 1309 catch (SemanticException e) { 1310 throw new InternalCompilerError("Cannot find class \"" + 1311 name + "\"; " + e.getMessage(), 1312 e); 1313 } 1314 } 1315 1316 public Named forName(String name) throws SemanticException { 1317 try { 1318 return systemResolver.find(name); 1319 } 1320 catch (SemanticException e) { 1321 if (! StringUtil.isNameShort(name)) { 1322 String containerName = StringUtil.getPackageComponent(name); 1323 String shortName = StringUtil.getShortNameComponent(name); 1324 1325 try { 1326 Named container = forName(containerName); 1327 if (container instanceof ClassType) { 1328 return classContextResolver((ClassType) container).find(shortName); 1329 } 1330 } 1331 catch (SemanticException e2) { 1332 } 1333 } 1334 1335 throw e; 1337 } 1338 } 1339 1340 public Type typeForName(String name) throws SemanticException { 1341 return (Type) forName(name); 1342 } 1343 1344 protected ClassType OBJECT_; 1345 protected ClassType CLASS_; 1346 protected ClassType STRING_; 1347 protected ClassType THROWABLE_; 1348 1349 public ClassType Object() { if (OBJECT_ != null) return OBJECT_; 1350 return OBJECT_ = load("java.lang.Object"); } 1351 public ClassType Class() { if (CLASS_ != null) return CLASS_; 1352 return CLASS_ = load("java.lang.Class"); } 1353 public ClassType String() { if (STRING_ != null) return STRING_; 1354 return STRING_ = load("java.lang.String"); } 1355 public ClassType Throwable() { if (THROWABLE_ != null) return THROWABLE_; 1356 return THROWABLE_ = load("java.lang.Throwable"); } 1357 public ClassType Error() { return load("java.lang.Error"); } 1358 public ClassType Exception() { return load("java.lang.Exception"); } 1359 public ClassType RuntimeException() { return load("java.lang.RuntimeException"); } 1360 public ClassType Cloneable() { return load("java.lang.Cloneable"); } 1361 public ClassType Serializable() { return load("java.io.Serializable"); } 1362 public ClassType NullPointerException() { return load("java.lang.NullPointerException"); } 1363 public ClassType ClassCastException() { return load("java.lang.ClassCastException"); } 1364 public ClassType OutOfBoundsException() { return load("java.lang.ArrayIndexOutOfBoundsException"); } 1365 public ClassType ArrayStoreException() { return load("java.lang.ArrayStoreException"); } 1366 public ClassType ArithmeticException() { return load("java.lang.ArithmeticException"); } 1367 1368 protected NullType createNull() { 1369 return new NullType_c(this); 1370 } 1371 1372 protected PrimitiveType createPrimitive(PrimitiveType.Kind kind) { 1373 return new PrimitiveType_c(this, kind); 1374 } 1375 1376 protected final NullType NULL_ = createNull(); 1377 protected final PrimitiveType VOID_ = createPrimitive(PrimitiveType.VOID); 1378 protected final PrimitiveType BOOLEAN_ = createPrimitive(PrimitiveType.BOOLEAN); 1379 protected final PrimitiveType CHAR_ = createPrimitive(PrimitiveType.CHAR); 1380 protected final PrimitiveType BYTE_ = createPrimitive(PrimitiveType.BYTE); 1381 protected final PrimitiveType SHORT_ = createPrimitive(PrimitiveType.SHORT); 1382 protected final PrimitiveType INT_ = createPrimitive(PrimitiveType.INT); 1383 protected final PrimitiveType LONG_ = createPrimitive(PrimitiveType.LONG); 1384 protected final PrimitiveType FLOAT_ = createPrimitive(PrimitiveType.FLOAT); 1385 protected final PrimitiveType DOUBLE_ = createPrimitive(PrimitiveType.DOUBLE); 1386 1387 public Object placeHolder(TypeObject o) { 1388 assert_(o); 1389 return placeHolder(o, new HashSet()); 1390 } 1391 1392 public Object placeHolder(TypeObject o, Set roots) { 1393 assert_(o); 1394 1395 if (o instanceof ClassType) { 1396 ClassType ct = (ClassType) o; 1397 1398 if (ct.isLocal() || ct.isAnonymous()) { 1401 throw new InternalCompilerError("Cannot serialize " + o + "."); 1402 } 1403 1404 return new PlaceHolder_c(ct); 1405 } 1406 1407 return o; 1408 } 1409 1410 protected UnknownType unknownType = new UnknownType_c(this); 1411 protected UnknownPackage unknownPackage = new UnknownPackage_c(this); 1412 protected UnknownQualifier unknownQualifier = new UnknownQualifier_c(this); 1413 1414 public UnknownType unknownType(Position pos) { 1415 return unknownType; 1416 } 1417 1418 public UnknownPackage unknownPackage(Position pos) { 1419 return unknownPackage; 1420 } 1421 1422 public UnknownQualifier unknownQualifier(Position pos) { 1423 return unknownQualifier; 1424 } 1425 1426 public Package packageForName(Package prefix, String name) throws SemanticException { 1427 return createPackage(prefix, name); 1428 } 1429 1430 public Package packageForName(String name) throws SemanticException { 1431 if (name == null || name.equals("")) { 1432 return null; 1433 } 1434 1435 String s = StringUtil.getShortNameComponent(name); 1436 String p = StringUtil.getPackageComponent(name); 1437 1438 return packageForName(packageForName(p), s); 1439 } 1440 1441 public Package createPackage(Package prefix, String name) { 1442 assert_(prefix); 1443 return new Package_c(this, prefix, name); 1444 } 1445 1446 public Package createPackage(String name) { 1447 if (name == null || name.equals("")) { 1448 return null; 1449 } 1450 1451 String s = StringUtil.getShortNameComponent(name); 1452 String p = StringUtil.getPackageComponent(name); 1453 1454 return createPackage(createPackage(p), s); 1455 } 1456 1457 1461 public ArrayType arrayOf(Type type) { 1462 assert_(type); 1463 return arrayOf(type.position(), type); 1464 } 1465 1466 public ArrayType arrayOf(Position pos, Type type) { 1467 assert_(type); 1468 return arrayType(pos, type); 1469 } 1470 1471 1474 protected ArrayType arrayType(Position pos, Type type) { 1475 return new ArrayType_c(this, pos, type); 1476 } 1477 1478 public ArrayType arrayOf(Type type, int dims) { 1479 return arrayOf(null, type, dims); 1480 } 1481 1482 public ArrayType arrayOf(Position pos, Type type, int dims) { 1483 if (dims > 1) { 1484 return arrayOf(pos, arrayOf(pos, type, dims-1)); 1485 } 1486 else if (dims == 1) { 1487 return arrayOf(pos, type); 1488 } 1489 else { 1490 throw new InternalCompilerError( 1491 "Must call arrayOf(type, dims) with dims > 0"); 1492 } 1493 } 1494 1495 1501 public Type typeForClass(Class clazz) throws SemanticException 1502 { 1503 if (clazz == Void.TYPE) return VOID_; 1504 if (clazz == Boolean.TYPE) return BOOLEAN_; 1505 if (clazz == Byte.TYPE) return BYTE_; 1506 if (clazz == Character.TYPE) return CHAR_; 1507 if (clazz == Short.TYPE) return SHORT_; 1508 if (clazz == Integer.TYPE) return INT_; 1509 if (clazz == Long.TYPE) return LONG_; 1510 if (clazz == Float.TYPE) return FLOAT_; 1511 if (clazz == Double.TYPE) return DOUBLE_; 1512 1513 if (clazz.isArray()) { 1514 return arrayOf(typeForClass(clazz.getComponentType())); 1515 } 1516 1517 return (Type) systemResolver.find(clazz.getName()); 1518 } 1519 1520 public Set getTypeEncoderRootSet(Type t) { 1521 return Collections.singleton(t); 1524 } 1525 1526 1534 public String getTransformedClassName(ClassType ct) { 1535 StringBuffer sb = new StringBuffer (ct.fullName().length()); 1536 if (!ct.isMember() && !ct.isTopLevel()) { 1537 return null; 1538 } 1539 while (ct.isMember()) { 1540 sb.insert(0, ct.name()); 1541 sb.insert(0, '$'); 1542 ct = ct.outer(); 1543 if (!ct.isMember() && !ct.isTopLevel()) { 1544 return null; 1545 } 1546 } 1547 1548 sb.insert(0, ct.fullName()); 1549 return sb.toString(); 1550 } 1551 1552 public String translatePackage(Resolver c, Package p) { 1553 return p.translate(c); 1554 } 1555 1556 public String translateArray(Resolver c, ArrayType t) { 1557 return t.translate(c); 1558 } 1559 1560 public String translateClass(Resolver c, ClassType t) { 1561 return t.translate(c); 1562 } 1563 1564 public String translatePrimitive(Resolver c, PrimitiveType t) { 1565 return t.translate(c); 1566 } 1567 1568 public PrimitiveType primitiveForName(String name) 1569 throws SemanticException { 1570 1571 if (name.equals("void")) return Void(); 1572 if (name.equals("boolean")) return Boolean(); 1573 if (name.equals("char")) return Char(); 1574 if (name.equals("byte")) return Byte(); 1575 if (name.equals("short")) return Short(); 1576 if (name.equals("int")) return Int(); 1577 if (name.equals("long")) return Long(); 1578 if (name.equals("float")) return Float(); 1579 if (name.equals("double")) return Double(); 1580 1581 throw new SemanticException("Unrecognized primitive type \"" + 1582 name + "\"."); 1583 } 1584 1585 protected LazyClassInitializer defaultClassInit; 1586 1587 public LazyClassInitializer defaultClassInitializer() { 1588 if (defaultClassInit == null) { 1589 defaultClassInit = new LazyClassInitializer_c(this); 1590 } 1591 1592 return defaultClassInit; 1593 } 1594 1595 public final ParsedClassType createClassType() { 1596 return createClassType(defaultClassInitializer(), null); 1597 } 1598 public final ParsedClassType createClassType(Source fromSource) { 1599 return createClassType(defaultClassInitializer(), fromSource); 1600 } 1601 1602 public final ParsedClassType createClassType(LazyClassInitializer init) { 1603 return createClassType(init, null); 1604 } 1605 1606 public ParsedClassType createClassType(LazyClassInitializer init, Source fromSource) { 1607 return new ParsedClassType_c(this, init, fromSource); 1608 } 1609 1610 public List defaultPackageImports() { 1611 List l = new ArrayList(1); 1612 l.add("java.lang"); 1613 return l; 1614 } 1615 1616 public PrimitiveType promote(Type t1, Type t2) throws SemanticException { 1617 if (! t1.isNumeric()) { 1618 throw new SemanticException( 1619 "Cannot promote non-numeric type " + t1); 1620 } 1621 1622 if (! t2.isNumeric()) { 1623 throw new SemanticException( 1624 "Cannot promote non-numeric type " + t2); 1625 } 1626 1627 return promoteNumeric(t1.toPrimitive(), t2.toPrimitive()); 1628 } 1629 1630 protected PrimitiveType promoteNumeric(PrimitiveType t1, PrimitiveType t2) { 1631 if (t1.isDouble() || t2.isDouble()) { 1632 return Double(); 1633 } 1634 1635 if (t1.isFloat() || t2.isFloat()) { 1636 return Float(); 1637 } 1638 1639 if (t1.isLong() || t2.isLong()) { 1640 return Long(); 1641 } 1642 1643 return Int(); 1644 } 1645 1646 public PrimitiveType promote(Type t) throws SemanticException { 1647 if (! t.isNumeric()) { 1648 throw new SemanticException( 1649 "Cannot promote non-numeric type " + t); 1650 } 1651 1652 return promoteNumeric(t.toPrimitive()); 1653 } 1654 1655 protected PrimitiveType promoteNumeric(PrimitiveType t) { 1656 if (t.isByte() || t.isShort() || t.isChar()) { 1657 return Int(); 1658 } 1659 1660 return t.toPrimitive(); 1661 } 1662 1663 1664 protected final Flags ACCESS_FLAGS = Public().Protected().Private(); 1665 1666 1667 protected final Flags LOCAL_FLAGS = Final(); 1668 1669 1670 protected final Flags FIELD_FLAGS = ACCESS_FLAGS.Static().Final() 1671 .Transient().Volatile(); 1672 1673 1674 protected final Flags CONSTRUCTOR_FLAGS = ACCESS_FLAGS 1675 .Synchronized().Native(); 1676 1677 1678 protected final Flags INITIALIZER_FLAGS = Static(); 1679 1680 1681 protected final Flags METHOD_FLAGS = ACCESS_FLAGS.Abstract().Static() 1682 .Final().Native() 1683 .Synchronized().StrictFP(); 1684 1685 1686 protected final Flags TOP_LEVEL_CLASS_FLAGS = ACCESS_FLAGS.clear(Private()) 1687 .Abstract().Final() 1688 .StrictFP().Interface(); 1689 1690 1691 protected final Flags MEMBER_CLASS_FLAGS = ACCESS_FLAGS.Static() 1692 .Abstract().Final() 1693 .StrictFP().Interface(); 1694 1695 1696 1697 protected final Flags LOCAL_CLASS_FLAGS = TOP_LEVEL_CLASS_FLAGS 1698 .clear(ACCESS_FLAGS); 1699 1700 public void checkMethodFlags(Flags f) throws SemanticException { 1701 if (! f.clear(METHOD_FLAGS).equals(Flags.NONE)) { 1702 throw new SemanticException( 1703 "Cannot declare method with flags " + 1704 f.clear(METHOD_FLAGS) + "."); 1705 } 1706 1707 if (f.isAbstract() && f.isPrivate()) { 1708 throw new SemanticException( 1709 "Cannot declare method that is both abstract and private."); 1710 } 1711 1712 if (f.isAbstract() && f.isStatic()) { 1713 throw new SemanticException( 1714 "Cannot declare method that is both abstract and static."); 1715 } 1716 1717 if (f.isAbstract() && f.isFinal()) { 1718 throw new SemanticException( 1719 "Cannot declare method that is both abstract and final."); 1720 } 1721 1722 if (f.isAbstract() && f.isNative()) { 1723 throw new SemanticException( 1724 "Cannot declare method that is both abstract and native."); 1725 } 1726 1727 if (f.isAbstract() && f.isSynchronized()) { 1728 throw new SemanticException( 1729 "Cannot declare method that is both abstract and synchronized."); 1730 } 1731 1732 if (f.isAbstract() && f.isStrictFP()) { 1733 throw new SemanticException( 1734 "Cannot declare method that is both abstract and strictfp."); 1735 } 1736 1737 checkAccessFlags(f); 1738 } 1739 1740 public void checkLocalFlags(Flags f) throws SemanticException { 1741 if (! f.clear(LOCAL_FLAGS).equals(Flags.NONE)) { 1742 throw new SemanticException( 1743 "Cannot declare local variable with flags " + 1744 f.clear(LOCAL_FLAGS) + "."); 1745 } 1746 } 1747 1748 public void checkFieldFlags(Flags f) throws SemanticException { 1749 if (! f.clear(FIELD_FLAGS).equals(Flags.NONE)) { 1750 throw new SemanticException( 1751 "Cannot declare field with flags " + 1752 f.clear(FIELD_FLAGS) + "."); 1753 } 1754 1755 checkAccessFlags(f); 1756 } 1757 1758 public void checkConstructorFlags(Flags f) throws SemanticException { 1759 if (! f.clear(CONSTRUCTOR_FLAGS).equals(Flags.NONE)) { 1760 throw new SemanticException( 1761 "Cannot declare constructor with flags " + 1762 f.clear(CONSTRUCTOR_FLAGS) + "."); 1763 } 1764 1765 checkAccessFlags(f); 1766 } 1767 1768 public void checkInitializerFlags(Flags f) throws SemanticException { 1769 if (! f.clear(INITIALIZER_FLAGS).equals(Flags.NONE)) { 1770 throw new SemanticException( 1771 "Cannot declare initializer with flags " + 1772 f.clear(INITIALIZER_FLAGS) + "."); 1773 } 1774 } 1775 1776 public void checkTopLevelClassFlags(Flags f) throws SemanticException { 1777 if (! f.clear(TOP_LEVEL_CLASS_FLAGS).equals(Flags.NONE)) { 1778 throw new SemanticException( 1779 "Cannot declare a top-level class with flag(s) " + 1780 f.clear(TOP_LEVEL_CLASS_FLAGS) + "."); 1781 } 1782 1783 if (f.isFinal() && f.isInterface()) { 1784 throw new SemanticException("Cannot declare a final interface."); 1785 } 1786 1787 checkAccessFlags(f); 1788 } 1789 1790 public void checkMemberClassFlags(Flags f) throws SemanticException { 1791 if (! f.clear(MEMBER_CLASS_FLAGS).equals(Flags.NONE)) { 1792 throw new SemanticException( 1793 "Cannot declare a member class with flag(s) " + 1794 f.clear(MEMBER_CLASS_FLAGS) + "."); 1795 } 1796 1797 if (f.isStrictFP() && f.isInterface()) { 1798 throw new SemanticException("Cannot declare a strictfp interface."); 1799 } 1800 1801 if (f.isFinal() && f.isInterface()) { 1802 throw new SemanticException("Cannot declare a final interface."); 1803 } 1804 1805 checkAccessFlags(f); 1806 } 1807 1808 public void checkLocalClassFlags(Flags f) throws SemanticException { 1809 if (f.isInterface()) { 1810 throw new SemanticException("Cannot declare a local interface."); 1811 } 1812 1813 if (! f.clear(LOCAL_CLASS_FLAGS).equals(Flags.NONE)) { 1814 throw new SemanticException( 1815 "Cannot declare a local class with flag(s) " + 1816 f.clear(LOCAL_CLASS_FLAGS) + "."); 1817 } 1818 1819 checkAccessFlags(f); 1820 } 1821 1822 public void checkAccessFlags(Flags f) throws SemanticException { 1823 int count = 0; 1824 if (f.isPublic()) count++; 1825 if (f.isProtected()) count++; 1826 if (f.isPrivate()) count++; 1827 1828 if (count > 1) { 1829 throw new SemanticException( 1830 "Invalid access flags: " + f.retain(ACCESS_FLAGS) + "."); 1831 } 1832 } 1833 1834 1840 protected List abstractSuperInterfaces(ReferenceType rt) { 1841 List superInterfaces = new LinkedList(); 1842 superInterfaces.add(rt); 1843 1844 for (Iterator iter = rt.interfaces().iterator(); iter.hasNext(); ) { 1845 ClassType interf = (ClassType)iter.next(); 1846 superInterfaces.addAll(abstractSuperInterfaces(interf)); 1847 } 1848 1849 if (rt.superType() != null) { 1850 ClassType c = rt.superType().toClass(); 1851 if (c.flags().isAbstract()) { 1852 superInterfaces.addAll(abstractSuperInterfaces(c)); 1855 } 1856 else { 1857 } 1861 } 1862 return superInterfaces; 1863 } 1864 1865 1872 public void checkClassConformance(ClassType ct) throws SemanticException { 1873 if (ct.flags().isInterface()) { 1874 return; 1876 } 1877 1878 List superInterfaces = abstractSuperInterfaces(ct); 1882 1883 for (Iterator i = superInterfaces.iterator(); i.hasNext(); ) { 1886 ReferenceType rt = (ReferenceType)i.next(); 1887 for (Iterator j = rt.methods().iterator(); j.hasNext(); ) { 1888 MethodInstance mi = (MethodInstance)j.next(); 1889 if (!mi.flags().isAbstract()) { 1890 continue; 1893 } 1894 1895 boolean implFound = false; 1896 ReferenceType curr = ct; 1897 while (curr != null && !implFound) { 1898 List possible = curr.methods(mi.name(), mi.formalTypes()); 1899 for (Iterator k = possible.iterator(); k.hasNext(); ) { 1900 MethodInstance mj = (MethodInstance)k.next(); 1901 if (!mj.flags().isAbstract() && 1902 ((isAccessible(mi, ct) && isAccessible(mj, ct)) || 1903 isAccessible(mi, mj.container().toClass()))) { 1904 1911 if (!equals(ct, mj.container()) && !equals(ct, mi.container())) { 1915 try { 1916 checkOverride(mj, mi); 1919 } 1920 catch (SemanticException e) { 1921 throw new SemanticException(e.getMessage(), 1925 ct.position()); 1926 } 1927 } 1928 else { 1929 } 1933 implFound = true; 1934 break; 1935 } 1936 } 1937 1938 if (curr == mi.container()) { 1939 break; 1944 } 1945 1946 curr = curr.superType() == null ? 1947 null : curr.superType().toReference(); 1948 } 1949 1950 1951 if (!implFound && !ct.flags().isAbstract()) { 1953 throw new SemanticException(ct.fullName() + " should be " + 1954 "declared abstract; it does not define " + 1955 mi.signature() + ", which is declared in " + 1956 rt.toClass().fullName(), ct.position()); 1957 } 1958 } 1959 } 1960 } 1961 1962 1966 public Type staticTarget(Type t) { 1967 return t; 1969 } 1970 1971 protected void initFlags() { 1972 flagsForName = new HashMap(); 1973 flagsForName.put("public", Flags.PUBLIC); 1974 flagsForName.put("private", Flags.PRIVATE); 1975 flagsForName.put("protected", Flags.PROTECTED); 1976 flagsForName.put("static", Flags.STATIC); 1977 flagsForName.put("final", Flags.FINAL); 1978 flagsForName.put("synchronized", Flags.SYNCHRONIZED); 1979 flagsForName.put("transient", Flags.TRANSIENT); 1980 flagsForName.put("native", Flags.NATIVE); 1981 flagsForName.put("interface", Flags.INTERFACE); 1982 flagsForName.put("abstract", Flags.ABSTRACT); 1983 flagsForName.put("volatile", Flags.VOLATILE); 1984 flagsForName.put("strictfp", Flags.STRICTFP); 1985 } 1986 1987 public Flags createNewFlag(String name, Flags after) { 1988 Flags f = Flags.createFlag(name, after); 1989 flagsForName.put(name, f); 1990 return f; 1991 } 1992 1993 public Flags NoFlags() { return Flags.NONE; } 1994 public Flags Public() { return Flags.PUBLIC; } 1995 public Flags Private() { return Flags.PRIVATE; } 1996 public Flags Protected() { return Flags.PROTECTED; } 1997 public Flags Static() { return Flags.STATIC; } 1998 public Flags Final() { return Flags.FINAL; } 1999 public Flags Synchronized() { return Flags.SYNCHRONIZED; } 2000 public Flags Transient() { return Flags.TRANSIENT; } 2001 public Flags Native() { return Flags.NATIVE; } 2002 public Flags Interface() { return Flags.INTERFACE; } 2003 public Flags Abstract() { return Flags.ABSTRACT; } 2004 public Flags Volatile() { return Flags.VOLATILE; } 2005 public Flags StrictFP() { return Flags.STRICTFP; } 2006 2007 public Flags flagsForBits(int bits) { 2008 Flags f = Flags.NONE; 2009 2010 if ((bits & Modifier.PUBLIC) != 0) f = f.Public(); 2011 if ((bits & Modifier.PRIVATE) != 0) f = f.Private(); 2012 if ((bits & Modifier.PROTECTED) != 0) f = f.Protected(); 2013 if ((bits & Modifier.STATIC) != 0) f = f.Static(); 2014 if ((bits & Modifier.FINAL) != 0) f = f.Final(); 2015 if ((bits & Modifier.SYNCHRONIZED) != 0) f = f.Synchronized(); 2016 if ((bits & Modifier.TRANSIENT) != 0) f = f.Transient(); 2017 if ((bits & Modifier.NATIVE) != 0) f = f.Native(); 2018 if ((bits & Modifier.INTERFACE) != 0) f = f.Interface(); 2019 if ((bits & Modifier.ABSTRACT) != 0) f = f.Abstract(); 2020 if ((bits & Modifier.VOLATILE) != 0) f = f.Volatile(); 2021 if ((bits & Modifier.STRICT) != 0) f = f.StrictFP(); 2022 2023 return f; 2024 } 2025 2026 public Flags flagsForName(String name) { 2027 Flags f = (Flags) flagsForName.get(name); 2028 if (f == null) { 2029 throw new InternalCompilerError("No flag named \"" + name + "\"."); 2030 } 2031 return f; 2032 } 2033 2034 public String toString() { 2035 return StringUtil.getShortNameComponent(getClass().getName()); 2036 } 2037 2038} 2039 | Popular Tags |