1 24 25 package org.aspectj.compiler.base.ast; 26 27 import org.aspectj.compiler.base.*; 28 import org.aspectj.compiler.base.cst.*; 29 30 import org.aspectj.compiler.base.bcg.ClassfileBuilder; 31 32 import java.io.*; 33 import java.util.*; 34 35 import java.lang.reflect.Modifier ; 36 37 import org.aspectj.compiler.crosscuts.ast.PointcutDec; 39 import org.aspectj.compiler.crosscuts.*; 40 41 53 public abstract class TypeDec extends Dec { 54 57 public void walkInnerInfo(InnerInfoPass w) { 58 int context = w.inType(this instanceof InterfaceDec); 59 w.enterType(this); 60 super.walkInnerInfo(w); 61 w.leaveType(); 62 w.restoreContext(context); 63 } 64 65 68 public void checkSpec() { 69 super.checkSpec(); 70 checkConstructorLoops(); 71 checkParentNonFinal(); 72 if (isInner() || isLocal()) { 73 checkNoStaticMembers(); 74 } 75 if (!isAnonymous()) { 76 TypeDec td = getEnclosingTypeDec(); 77 while (td != null) { 78 if (td.getId().equals(getId())) { 79 showError("the name of this inner type conflicts with the name of an enclosing type: " + getId()); 80 } 81 td = td.getEnclosingTypeDec(); 82 } 83 } 84 85 if (fromSource()) { 86 if (!getType().isAbstract()) { 87 getNameType().ensureNoAbstractDecs(); 88 } 89 if (isPackageMember()) { 90 PackageSO p = getTypeManager().findPackage(getPackageName()); 91 if (p.containsSubPackage(getId())) { 92 showError(getFullName() + " clashes with package of same name"); 93 } 94 } 95 } 96 } 97 98 private void checkNoStaticMembers() { 99 for (int i=0, N=body.size(); i < N; i++) { 100 Dec dec = body.get(i); 101 if (!dec.isStatic()) continue; 102 if (dec instanceof FieldDec) { 103 FieldDec fd = (FieldDec)dec; 104 if (!fd.isConstant()) { 105 dec.showError("all static fields in inners must be constant static finals"); 106 } 107 } else { 108 dec.showError("inner classes cannot have static declarations"); 109 } 110 } 111 } 112 113 private void checkParentNonFinal() { 114 if (((NameType)getSuperClassType()).isFinal()) { 115 showError("May not extend a final class"); 116 } 117 } 118 119 private void checkConstructorLoops() { 120 for (int i = 0, len = body.size(); i < len; i++) { 121 Dec d = body.get(i); 122 if (! (d instanceof ConstructorDec)) continue; 123 ConstructorDec cd = (ConstructorDec) d; 124 Set alreadySeen = new java.util.HashSet (); 125 while (! cd.isSuper()) { 126 if (alreadySeen.contains(cd)) { 127 ((ConstructorBody)cd.getBody()).getConstructorCall() 128 .showError("a constructor may not directly or indirectly invoke itself"); 129 break; 130 } 131 alreadySeen.add(cd); 132 cd = cd.getNextConstructorDec(); 133 } 134 } 135 } 136 137 140 public ASTObject walkMemberMunger(MemberClassMunger w) { 141 w.enterType(getNameType()); 142 if (isInner()) { 143 final AST ast = getAST(); 144 NameType enclosingInstanceType = getEnclosingInstanceType(); 145 FieldDec enclosingInstanceField = 146 ast.makeField(ast.makeModifiers(Modifiers.FINAL | Modifiers.PRIVATE), 147 enclosingInstanceType, 148 "this$" + enclosingInstanceType.getId()); 149 w.pushField(enclosingInstanceField); 150 super.walkMemberMunger(w); 151 w.popField(); 152 153 addFieldDec(enclosingInstanceField); 154 getBody().add(0, enclosingInstanceField); 155 } else { 156 List fields = w.saveFields(); 157 super.walkMemberMunger(w); 158 w.restoreFields(fields); 159 } 160 w.leaveType(); 161 return this; 162 } 163 164 public void walkFlow(FlowCheckerPass ww) { 167 170 Decs body = getBody(); 171 int len = body.size(); 172 173 176 FlowCheckerPass.Set staticFinalFields = FlowCheckerPass.Set.getNone(); 177 FlowCheckerPass.Set dynamicFinalFields = FlowCheckerPass.Set.getNone(); 178 179 for (int i = 0; i < len; i++) { 180 Dec d = body.get(i); 181 if ((d instanceof FieldDec) && d.isFinal()) { 182 FieldDec dd = (FieldDec) d; 183 if (d.isStatic()) { 184 staticFinalFields = staticFinalFields.add(dd); 185 } else { 186 dynamicFinalFields = dynamicFinalFields.add(dd); 187 } 188 } 189 } 190 191 194 197 FlowCheckerPass w = new FlowCheckerPass(getCompiler(), this); 198 199 202 for (int i = 0; i < len; i++) { 204 Dec d = body.get(i); 205 if (! d.isStatic()) continue; 206 if ((d instanceof FieldDec) && d.isFinal()) { 207 FieldDec fd = (FieldDec) d; 208 if (fd.getInitializer() != null) { 209 w.setVars(w.getVars().addAssigned(fd)); 211 } else { 212 w.setVars(w.getVars().addUnassigned(fd)); 213 } 214 215 216 } else if (d instanceof InitializerDec) { 217 w.process(d); 218 } 219 } 220 221 FlowCheckerPass.Set staticAssigned = w.getVars().getDa(); 224 for (FlowCheckerPass.Set x = staticFinalFields; ! x.isEmpty(); x = x.rest()) { 225 if (! staticAssigned.contains(x.first())) { 226 w.showVarError(this, 227 x.first(), 228 "Field " + x.first().getId() 229 + " might not be initialized"); 230 } 231 } 232 233 238 staticAssigned = ww.getVars().getDa().union(staticFinalFields); 239 w = new FlowCheckerPass(getCompiler(), staticAssigned, this); 240 241 for (int i = 0; i < len; i++) { 243 Dec d = body.get(i); 244 if (d.isStatic()) continue; 245 if ((d instanceof FieldDec) && d.isFinal()) { 246 FieldDec fd = (FieldDec) d; 247 if (fd.getInitializer() != null) { 248 w.setVars(w.getVars().addAssigned(fd)); 250 } else { 251 w.setVars(w.getVars().addUnassigned(fd)); 252 } 253 } else if (d instanceof InitializerDec) { 254 w.process(d); 255 } 256 } 257 258 FlowCheckerPass.Vars preConstructorVars = w.getVars(); 259 260 FlowCheckerPass.Set dynamicAssigned = 261 staticAssigned.union(dynamicFinalFields); 262 263 TypeDs initializerThrows = w.getCheckedExns(); 264 265 for (int i = 0; i < len; i++) { 272 Dec d = body.get(i); 273 if (! (d instanceof ConstructorDec)) continue; 274 ConstructorDec cd = (ConstructorDec) d; 275 if (isAnonymous()) { 276 cd.setThrows(initializerThrows); 277 } 278 if (cd.isSuper()) { 279 w = new FlowCheckerPass(getCompiler(), preConstructorVars, this); 280 w.process(d); 281 FlowCheckerPass.Set currentAssigned = w.getVars().getDa(); 283 for (FlowCheckerPass.Set x = dynamicFinalFields; ! x.isEmpty(); x = x.rest()) { 284 if (! currentAssigned.contains(x.first())) { 285 w.showVarError(this, 286 x.first(), 287 "Field " + x.first().getId() 288 + " might not be initialized"); 289 } 290 } 291 } else { 292 w = new FlowCheckerPass(getCompiler(), dynamicAssigned, this); 293 w.process(d); 294 } 295 } 296 297 301 for (int i = 0; i < len; i++) { 302 Dec d = body.get(i); 303 if ((d instanceof FieldDec) 304 || (d instanceof InitializerDec) 305 || (d instanceof ConstructorDec)) 306 continue; 307 w = new FlowCheckerPass(getCompiler(), dynamicAssigned, this); 308 w.process(d); 309 } 310 311 } 313 314 public int getDepth() { 316 if (getEnclosingTypeDec() == null) return 0; 317 else return 1 + getEnclosingTypeDec().getDepth(); 318 } 319 320 public void preMove(MovingWalker walker) { 321 walker.pushLexicalType(getType()); 322 } 323 324 public void preCopy(CopyWalker walker, ASTObject oldObject) { 325 walker.pushLexicalType(getType()); 326 } 327 328 331 public ASTObject postCopy(CopyWalker walker, ASTObject oldObject) { 332 TypeDec oldTypeDec = (TypeDec)oldObject; 333 if (walker.hasToType()) { 340 this.setEnclosingTypeDec(walker.getToType().getTypeDec()); 342 } else { 344 this.setEnclosingTypeDec(oldTypeDec.getEnclosingTypeDec()); 345 } 346 return super.postCopy(walker, oldObject); 347 } 348 349 public ASTObject postMove(MovingWalker walker) { 350 for (int i = 0; i < body.size(); i++) { 352 body.get(i).setDeclaringType(getType()); 353 } 355 356 357 walker.popLexicalType(); 358 return super.postMove(walker); 359 } 360 361 public Set memberTypeNames = null; 362 363 protected NameType type = null; 364 public Type getType() { 365 return getNameType(); 366 } 367 368 public void setType(NameType type) { 369 this.type = type; 370 } 371 372 public NameType getNameType() { 373 if (type == null) { 374 type = new NameType(this); 375 } 377 return type; 378 } 379 380 public TypeDec getBytecodeTypeDec() { return this; } 382 383 public SemanticObject makeCorrespondingSemanticObject() { return getType(); } 384 385 private Set extraWithinTypes = new HashSet(); 386 public Set getExtraWithinTypes() { return extraWithinTypes; } 387 public void addExtraWithinType(Type type) { extraWithinTypes.add(type); } 388 389 public Type getSuperClassType() { return getTypeManager().getObjectType(); } 390 391 public Collection getSuperInterfaceTypes() { 392 return makeInterfaceTypesFromTypeDs(superInterfaces); 393 } 394 395 public void addSuperInterfaceType(Type newSuperType) { 396 TypeDs list = this.getSuperInterfaces(); 397 if (list == null) { 398 list = getAST().makeTypeDs(); this.setSuperInterfaces(list); 400 } 401 list.add(newSuperType.makeTypeD()); 402 } 403 404 405 406 private TypeDec enclosingTypeDec = null; 408 409 public void setEnclosingTypeDec(TypeDec dec) { 410 enclosingTypeDec = dec; 411 } 413 414 public TypeDec getEnclosingTypeDec() { 415 return enclosingTypeDec; 416 } 417 418 public TypeDec getDeclaringTypeDec() { 419 return getEnclosingTypeDec(); 420 } 421 422 public TypeDec getOutermostTypeDec() { 423 TypeDec immediateParent = getEnclosingTypeDec(); 424 if (immediateParent == null) return this; 425 return immediateParent.getOutermostTypeDec(); 426 } 427 428 public Type getOutermostType() { 429 TypeDec immediateParent = getEnclosingTypeDec(); 430 if (immediateParent == null) return this.getType(); 431 return immediateParent.getOutermostType(); 432 } 433 434 440 public boolean isInnerType() { 441 return getDeclaringTypeDec() != null; 442 } 443 444 public boolean isInnerTypeOf(TypeDec parentType) { 445 TypeDec immediateParent = getDeclaringTypeDec(); 446 if (immediateParent == null) return false; 447 if (immediateParent == parentType) return true; 448 return immediateParent.isInnerTypeOf(parentType); 449 } 450 451 455 public boolean hasGlobalName() { 456 if (isLocal()) return false; 457 TypeDec immediateParent = getDeclaringTypeDec(); 458 if (immediateParent == null) return true; 459 return immediateParent.hasGlobalName(); 460 } 461 462 463 public boolean isLocallyDefined() { 464 return isLocal(); 465 } 466 467 public abstract boolean isAnonymous(); 468 469 470 public boolean canOverride(Dec otherDec) { 471 return true; 472 } 473 474 500 501 502 public boolean isRoot() { 503 return this == getTypeManager().getObjectType().getTypeDec(); 504 } 505 506 public boolean isConcrete() { 507 return !(this instanceof InterfaceDec); 508 } 509 510 private int localTypesCounter = 0; 511 public int allocateLocalTypeIndex() { 512 return ++localTypesCounter; 513 } 514 515 516 523 public String getExtendedId() { 524 if (getEnclosingTypeDec() != null) { 525 return getEnclosingTypeDec().getExtendedId() + '$' + id; 526 } else { 527 return id; 528 } 529 } 530 531 538 public String getSourceExtendedId() { 539 if (getEnclosingTypeDec() != null) { 540 return getEnclosingTypeDec().getSourceExtendedId() + '.' + id; 541 } else { 542 return id; 543 } 544 } 545 546 549 protected Collection makeInterfaceTypesFromTypeDs(TypeDs typeDs) { 550 if (typeDs == null || typeDs.size() == 0) return Collections.EMPTY_LIST; 551 552 List ret = new ArrayList(typeDs.size()); 553 554 for (int i = 0; i < typeDs.size(); i++) { 555 Type type = typeDs.get(i).getType(); 556 if (!type.isInterface()) { 557 typeDs.get(i).showError("interface required, not " + type.toShortString()); 558 } else if (ret.contains(type)) { 559 typeDs.get(i).showError("repeated parent interface " + type.toShortString()); 560 } else { 561 ret.add(type); 562 } 563 } 564 565 return ret; 566 } 567 568 protected void addPointcutDec(PointcutDec pointcutDec) { 569 type.addPointcut(pointcutDec); 570 } 571 572 protected void addFieldDec(FieldDec fieldDec) { 573 type.addField(fieldDec); 574 } 575 576 protected void addMethodDec(MethodDec methodDec) { 577 if (getModifiers().isStrict() && !methodDec.getModifiers().isAbstract()) { 578 methodDec.getModifiers().setStrict(true); 579 } 580 type.addMethod(methodDec); 581 } 582 583 protected void addConstructorDec(ConstructorDec constructorDec) { 584 if (getModifiers().isStrict()) constructorDec.getModifiers().setStrict(true); 586 type.addConstructor(constructorDec); 587 } 588 589 protected void addTypeDec(TypeDec typeDec) { 590 if (getModifiers().isStrict()) typeDec.getModifiers().setStrict(true); 591 typeDec.enclosingTypeDec = this; 592 typeDec.setAllEnclosingTypes(this.getType()); 593 ((NameType)getType()).addInnerType(typeDec); 594 } 595 596 public void addMemberTypeDec(TypeDec memberDec) { 597 addTypeDec(memberDec); 598 getBody().add(memberDec); 599 } 600 601 public void addMemberMethodDec(MethodDec memberDec) { 602 addMethodDec(memberDec); 603 getBody().add(memberDec); 604 } 605 606 public void addIntroducedDec(Dec dec) { 607 getBody().add(dec); 608 609 SemanticObject oldSO = null; 610 if (dec instanceof MethodDec) { 611 oldSO = type.methods.addIntroduced(dec.getCorrespondingSemanticObject()); 612 } else if (dec instanceof FieldDec) { 613 oldSO = type.fields.addIntroduced(dec.getCorrespondingSemanticObject()); 614 } else if (dec instanceof ConstructorDec) { 615 oldSO = type.constructors.addIntroduced(dec.getCorrespondingSemanticObject()); 616 } 617 618 if (oldSO != null) { 619 getBody().remove(oldSO.getCorrespondingDec()); 620 } 621 } 622 623 protected void addInitializerDec(InitializerDec dec) { 624 } 626 627 628 protected void addDec(Dec dec) { 630 if (!dec.isLanguageVisible() && !( 632 dec.getId().equals("aspectOf") || dec.getId().equals("hasAspect"))) return; 633 634 if (dec instanceof TypeDec) { 635 addTypeDec((TypeDec)dec); 636 } else if (dec instanceof MethodDec) { 637 addMethodDec((MethodDec)dec); 638 } else if (dec instanceof FieldDec) { 639 addFieldDec((FieldDec)dec); 640 } else if (dec instanceof ConstructorDec) { 641 addConstructorDec((ConstructorDec)dec); 642 } else if (dec instanceof PointcutDec) { 643 addPointcutDec((PointcutDec)dec); 644 } else if (dec instanceof InitializerDec) { 645 addInitializerDec((InitializerDec)dec); 646 } else if (dec instanceof VarDec) { 647 showWarning("shouldn't be found in a class"); 648 } else { 649 dec.showWarning("shouldn't be found in " + this.toShortString()); 650 } 651 } 652 653 public final String getPackageName() { 654 if (getEnclosingTypeDec() != null) { 655 return getEnclosingTypeDec().getPackageName(); 656 } else { 657 return getCompilationUnit().getPackageName(); 658 } 659 } 660 661 private ConstructorDec soleConstructorDec; 662 public void setSoleConstructorDec(ConstructorDec d) { 663 soleConstructorDec = d; 664 } 665 666 public ConstructorDec getSoleConstructorDec() { 667 return soleConstructorDec; 668 } 669 670 671 public void addInnerTypes() { 672 if (memberTypeNames != null) { 674 for (Iterator i = memberTypeNames.iterator(); i.hasNext(); ) { 675 String name = (String )i.next(); 676 if (name == null || name.length() == 0 || 677 !Character.isJavaIdentifierStart(name.charAt(0))) { 678 getCompiler().showMessage("ignoring invalid inner class attribute: " + 680 getExtendedId()+'$'+name); 681 continue; 682 } 683 684 Type innerType = getTypeManager().findType(getPackageName(), 686 getExtendedId()+'$'+name); 687 if (innerType == null) { 688 getCompiler().showMessage("ignoring invalid inner class attribute: " + 689 getExtendedId()+'$'+name); 690 continue; 691 } 692 addTypeDec(innerType.getTypeDec()); 693 } 694 } 695 696 Decs decs = getBody(); 697 if (decs == null) { 698 if (getOptions().torture) showWarning("no body for " + this); 699 return; 700 } 701 final int N = decs.size(); 702 for(int i=0; i < N; i++) { 703 if (decs.get(i) instanceof TypeDec) { 704 addDec(decs.get(i)); 705 } 706 } 707 } 708 709 710 public void addDecs(NameType toThis) { 711 Decs decs = getBody(); 712 if (decs == null) { 713 if (getOptions().torture) showWarning("no body for " + this); 714 return; 715 } 716 final int N = decs.size(); 717 for(int i=0; i < N; i++) { 718 if (! (decs.get(i) instanceof TypeDec) ) { 720 addDec(decs.get(i)); 721 } 722 } 723 } 724 725 private ConstructorDec makeDefaultConstructor() { 726 final AST ast = getAST(); 727 728 ConstructorCallExpr superCall = null; 729 if (!isRoot()) { 730 Constructor superConstructor = 731 getSuperClassType().getConstructor(getBody(), ast.makeExprs(), true); 732 superCall = ast.makeSuperConstructorCall(superConstructor); 733 } 734 ConstructorDec ret = ast.makeConstructor( 735 ast.makeModifiers(getModifiers().getAccessValue()), 738 ast.makeFormals(), ast.makeTypeDs(), 739 superCall, ast.makeStmts()); 740 ret.setLanguageVisible(); 741 ret.setSourceLocation(getSourceLocation()); 743 return ret; 744 } 745 746 void addDefaultConstructor() { 747 if (body == null || getType().isObject()) return; 749 750 if (isAnonymous()) return; 752 753 755 ConstructorDec ret = makeDefaultConstructor(); 756 addConstructorDec(ret); 757 body.add(ret); 758 } 759 760 public void postIntroductionFinish() { 762 if (((NameType)getType()).getConstructors().size() == 0) { 763 if (!isAnonymous()) addDefaultConstructor(); 764 } else if (isAnonymous()) { 765 showError("Anonymous classes cannot define constructors"); 766 } 767 } 768 769 public void addToBody(Dec dec) { 771 getBody().add(dec); 772 } 773 774 public void addToBodyAndType(Dec dec) { 775 addToBody(dec); 776 addDec(dec); 777 } 778 779 780 public String getPrettyString() { 781 return getType().getPrettyString(); 782 } 783 784 785 public String toString() { 786 return getType().getString(); 787 } 788 789 public String toShortString() { 790 return getType().getString(); 791 } 792 793 public void fixAST(ASTFixerPass fixer) { 794 TypeDec saveTypeDec = fixer.getInTypeDec(); 795 fixer.setInTypeDec(this); 796 this.walk(fixer); 797 fixer.setInTypeDec(saveTypeDec); 798 799 if (getOptions().jvmTorture) return; 802 803 NameType myType = getNameType(); 804 if (myType.isInterface()) return; 805 if (!myType.isAbstract()) return; 806 807 for (Iterator i = myType.getMethods().iterator(); i.hasNext(); ) { 808 Method m = (Method)i.next(); 809 if (m.getDeclaringType().isInterface() && 810 m.getMethodDec().getBody() == null && 811 !m.getMethodDec().isIntroduced()) 812 { 813 getBody().add((MethodDec)m.getMethodDec().copy()); 814 } 815 } 816 } 817 818 protected void walkExtendsAndImplements(ScopeWalker walker) { 819 if (superInterfaces != null) walker.process(superInterfaces); 820 } 821 822 protected void walkBody(ScopeWalker walker) { 823 walker.process(body); 824 } 825 826 protected Scope getEnclosingScope(boolean justTypeGraph) { 828 if (isLocal()) { 829 getCompiler().internalError(this, "trying to get simple scope for a local type"); 830 } 831 TypeDec td = getEnclosingTypeDec(); 832 if (td == null) { 833 return getCompilationUnit().getScope(); 834 } else { 835 Scope ret = new TypeScope(getCompiler(), td.getEnclosingScope(justTypeGraph), td.getType()); 836 if (justTypeGraph) td.addToTypeGraph(); 837 else td.buildSignatures(); 838 return ret; 839 } 840 } 841 842 public void addToTypeGraph() { 844 if (!fromSource()) getNameType().addToTypeGraph(); 845 else addThisToTypeGraph(new ScopeWalker(getCompiler(), getEnclosingScope(true))); 846 } 847 848 public void buildSignatures() { 849 if (!fromSource()) getNameType().buildSignatures(); 850 else buildThisSignatures(new ScopeWalker(getCompiler(), getEnclosingScope(false))); 851 } 852 853 private boolean isUnsupportedType() { 854 String p = getPackageName(); 855 return p != null && p.equals("java.lang") && 856 (getId().equals("Object") || getId().equals("String")); 857 } 858 859 private boolean addToTypeGraphDone = false; 860 private boolean addedInnersDone = false; 861 private boolean addToTypeGraphInProgress = false; 862 863 868 public void addToTypeGraph(ScopeWalker walker) { 869 if (isUnsupportedType()) { 870 showError("can not compile " + getPrettyString() + " (compiler limitation)"); 871 return; 872 } 873 874 addThisToTypeGraph(walker); 875 addInnersToTypeGraph(walker); 876 } 877 878 879 private void addThisToTypeGraph(ScopeWalker walker) { 880 if (addToTypeGraphDone) return; 881 882 883 if (addToTypeGraphInProgress) { 884 StringBuffer message = new StringBuffer ("cyclic inheritance, "); 885 886 getWorld().getBuildingTypeGraph(); 887 boolean foundThis = false; 888 List l = getWorld().getBuildingTypeGraph(); 889 for (Iterator i = l.iterator(); i.hasNext(); ) { 890 TypeDec td = (TypeDec)i.next(); 891 if (td == this) foundThis = true; 892 if (foundThis) { 893 message.append(td.toShortString()); 894 message.append(" -> "); 895 } 896 } 897 message.append(this.toShortString()); 898 899 showError(message.toString()); 900 return; 901 } 902 getWorld().pushBuildingTypeGraph(this); 903 addToTypeGraphInProgress = true; 904 905 walker.addTypeDec(this); 906 907 walkExtendsAndImplements(walker); 909 getNameType().addToTypeGraph(); 912 getWorld().popBuildingTypeGraph(); 913 addToTypeGraphDone = true; 914 } 915 916 private void addInnersToTypeGraph(ScopeWalker walker) { 917 if (addedInnersDone) return; 918 addedInnersDone = true; 919 920 walker.pushScope(new TypeScope(getCompiler(), null, getType())); 921 922 Decs decs = getBody(); 923 for (int i=0, N=decs.size(); i<N; i++) { 924 Dec dec = decs.get(i); 925 if (dec instanceof TypeDec) ((TypeDec)dec).addToTypeGraph(walker); 926 } 927 928 boolean saveWalkBodies = walker.walkBodies(); 931 walker.setWalkBodies(false); 932 walkBody(walker); 933 walker.setWalkBodies(saveWalkBodies); 934 935 walker.popScope(); 936 } 937 938 939 940 private boolean buildSignaturesDone = false; 941 private boolean buildSignaturesInProgress = false; 942 private boolean buildInnerSignaturesDone = false; 943 944 953 public void buildSignatures(ScopeWalker walker) { 954 buildThisSignatures(walker); 955 buildInnerSignatures(walker); 956 } 957 958 private void buildThisSignatures(ScopeWalker walker) { 959 if (buildSignaturesDone) return; 960 if (buildSignaturesInProgress) { 961 showError("circularity detected, already building signatures"); 962 return; 963 } 964 buildSignaturesInProgress = true; 965 966 addToTypeGraph(walker); 967 968 getNameType().buildSignatures(); 969 972 postIntroductionFinish(); 973 974 buildSignaturesDone = true; 975 } 976 977 private void buildInnerSignatures(ScopeWalker walker) { 978 if (buildInnerSignaturesDone) return; 979 buildInnerSignaturesDone = true; 980 981 walker.pushScope(new TypeScope(getCompiler(), null, getType())); 982 983 Decs decs = getBody(); 984 for (int i=0, N=decs.size(); i<N; i++) { 985 Dec dec = decs.get(i); 986 if (dec instanceof TypeDec) ((TypeDec)dec).buildSignatures(walker); 987 } 988 walker.popScope(); 989 } 990 991 992 997 public void walkScope(ScopeWalker walker) { 998 if (! (walker instanceof NameHygienePass) ) { 1000 if (walker.walkBodies()) buildSignatures(walker); 1001 else addToTypeGraph(walker); 1002 } else { 1003 walkExtendsAndImplements(walker); 1004 } 1005 1006 walker.pushScope(new TypeScope(getCompiler(), null, getType())); 1008 1009 walkBody(walker); 1011 walker.popScope(); 1013 } 1014 1015 public FieldDec joinPointFactoryDec = null; 1017 1018 public List joinPoints0 = new ArrayList(); 1020 public List joinPoints1 = new ArrayList(); 1021 public List joinPoints2 = new ArrayList(); 1022 1023 public String getFullName() { 1025 String fullName = null; 1026 1028 if (fullName == null) { 1029 if (getEnclosingTypeDec() != null) { 1030 fullName = getEnclosingTypeDec().getFullName() + '$' + getId(); 1031 } else { 1032 String packageName = getPackageName(); 1033 String id = getId(); 1034 fullName = packageName == null ? id : packageName + '.' + id; 1035 } 1036 } 1038 return fullName; 1039 } 1040 1041 1044 1045 public void setInnerDiscoveries(boolean a, boolean b, boolean c) { 1046 setIsInner(b); 1047 } 1048 1049 public void setIsInner(boolean b) { 1050 if (b) { 1051 throw new RuntimeException ("TypeDec " + this + " should never be inner"); 1052 } 1053 } 1054 1055 public Type getOutermostBytecodeType() { 1056 if (isPackageMember()) { 1057 return getType(); 1058 } else { 1059 return super.getOutermostBytecodeType(); 1060 } 1061 } 1062 1063 public Type getOutermostLexicalType() { 1064 if (isPackageMember()) { 1065 return getType(); 1066 } else { 1067 return super.getOutermostLexicalType(); 1068 } 1069 } 1070 1071 1072 1073 1076 public boolean isInner() { return false; } 1077 public void setLocal() { } public boolean isLocal() { 1079 ASTObject parent = getParent(); 1080 if (parent == null) return false; 1081 parent = parent.getParent(); 1082 if (parent == null || parent instanceof TypeDec 1083 || parent instanceof CompilationUnit) return false; 1084 return true; 1085 } 1086 1087 public boolean isPackageMember() { 1088 ASTObject parent = getParent(); 1089 if (parent == null) return false; 1090 parent = parent.getParent(); 1091 if (parent == null || !(parent instanceof CompilationUnit)) return false; 1092 return true; 1093 } 1094 1095 public NameType getEnclosingInstanceType() { 1097 return (NameType)getDeclaringType(); 1098 } 1099 public TypeDec getEnclosingInstanceTypeDec() { 1100 return getEnclosingInstanceType().getTypeDec(); 1101 } 1102 1103 private Set initializerExecutionJoinPoints = new HashSet(); 1105 public Set getInitializerExecutionJoinPoints() { 1106 return initializerExecutionJoinPoints; 1107 } 1108 1109 1112 public void walkForwardReference(ForwardReferenceChecker w) { 1113 this.walk(w.createTypeChecker(this)); 1114 } 1115 1116 1119 public void walkAnalysis(LocalClassPass.AnalysisWalker walker) { 1120 if (isLocal()) { 1121 walker.enterTypeDec(this); 1122 setId(walker.makeNewId(this)); 1123 } 1124 walker.inType(); 1125 this.walk(walker); 1126 if (isLocal()) 1127 walker.leaveTypeDec(); 1128 } 1129 1130 1133 public void preLift(LocalClassPass.LiftWalker walker) { 1134 walker.pushPendingDecs(); 1135 } 1136 1137 public ASTObject postLift(LocalClassPass.LiftWalker walker) { 1138 initializersToConstructors(); 1139 walker.popPendingDecsInto(this); 1140 if (isLocal()) { 1141 walker.addToPendingDecs(this); 1142 return null; 1143 } else { 1144 return this; 1145 } 1146 } 1147 1148 public void collectInitializers(boolean collectSynthetics) { 1149 collectInitializers(true, collectSynthetics); 1150 collectInitializers(false, collectSynthetics); 1151 } 1152 1153 Field assertionsDisabledField = null; 1154 1156 public Field getAssertionsDisabledField() { 1157 if (assertionsDisabledField != null) return assertionsDisabledField; 1158 1159 final AST ast = getAST(); 1160 Modifiers mods = 1161 ast.makeModifiers(Modifiers.STATIC|Modifiers.FINAL); 1162 Type type = getTypeManager().booleanType; 1163 String id = "ajc$assertionsDisabled"; 1164 Expr init = ast.makeUnop("!", 1165 ast.makeCall(ast.makeLiteral(getOutermostType()), 1166 "desiredAssertionStatus")); 1167 FieldDec adf = ast.makeField(mods, type, id, init); 1168 adf.setDeclaringType(getType()); 1169 assertionsDisabledField = adf.getField(); 1171 return assertionsDisabledField; 1172 } 1173 1174 public void addAssertionField() { 1175 if (assertionsDisabledField != null) { 1176 getBody().add(0, assertionsDisabledField.getFieldDec()); 1177 } 1178 } 1179 1180 public void collectInitializers(boolean isStatic, boolean collectSynthetics) { 1181 if (isStatic && 1184 (!collectSynthetics || getCompiler().willGenerateSourceCode())) { 1185 if (this instanceof InterfaceDec) return; 1186 } 1187 1188 1189 final AST ast = getAST(); 1190 Stmts stmts = ast.makeStmts(); 1191 InitializerDec ret = null; 1192 boolean singleInitializer = true; 1193 1194 for (ListIterator i = body.iterator(); i.hasNext(); ) { 1195 Dec memDec = (Dec)i.next(); 1196 if (isStatic != memDec.isStatic()) continue; 1197 1199 if (memDec instanceof InitializerDec) { 1200 InitializerDec iDec = (InitializerDec)memDec; 1201 stmts.addAll(iDec.getBody().getStmts()); 1204 if (ret == null) ret = iDec; 1205 else singleInitializer = false; 1206 i.remove(); 1207 } else if (memDec instanceof FieldDec) { 1208 FieldDec fDec = (FieldDec)memDec; 1209 if (collectSynthetics || fDec.isLanguageVisible()) { 1210 fDec.getAssignExpr(); } 1212 } 1213 } 1214 1215 if (ret == null || true) { if (stmts.size() == 1 && stmts.get(0) instanceof BlockStmt) { 1219 stmts = ((BlockStmt)stmts.get(0)).getStmts(); 1220 } 1222 1223 if (isStatic) ret = ast.makeStaticInitializer(stmts); 1224 else ret = ast.makeInitializer(stmts); 1225 } 1227 ret.setSourceLocation(getSourceLocation()); 1228 body.add(ret); 1229 } 1231 1232 public InitializerDec getSingleInitializerDec(boolean isStatic) { 1233 for (ListIterator i = body.iterator(); i.hasNext(); ) { 1234 Dec memDec = (Dec)i.next(); 1235 if (memDec instanceof InitializerDec && 1236 isStatic == memDec.isStatic()) return (InitializerDec)memDec; 1237 } 1238 showError("no initializer for: " + this); 1239 return null; 1240 } 1241 1242 1243 private void initializersToConstructors() { 1248 final AST ast = getAST(); 1249 Stmts stmts = ast.makeStmts(); 1250 1251 for (Iterator i = getBody().iterator(); i.hasNext(); ) { 1253 Object o = i.next(); 1254 if (o instanceof InitializerDec) { 1255 InitializerDec iDec = (InitializerDec) o; 1256 if (iDec.isStatic()) { 1257 if (iDec.getBody().getStmts().size == 0) i.remove(); 1258 continue; 1259 } 1260 i.remove(); 1261 Stmt iStmt = iDec.getBody(); 1262 if (iStmt instanceof BlockStmt && 1263 ((BlockStmt)iStmt).getStmts().size() == 0) 1264 continue; 1265 stmts.add(0, iStmt); 1266 } 1267 } 1268 for (Iterator i = getBody().iterator(); i.hasNext(); ) { 1270 Object o = i.next(); 1271 if (o instanceof ConstructorDec) { 1272 ConstructorDec cDec = (ConstructorDec) o; 1273 ConstructorCallExpr call = 1275 ((ConstructorBody)cDec.getBody()).getConstructorCall(); 1276 if (call != null && !call.getIsSuper()) continue; 1277 1278 Stmts newStmts = (Stmts) CopyWalker.copy(stmts); 1279 cDec.getBody().getStmts().addAll(0, newStmts); 1281 } 1282 } 1283 } 1284 1285 1288 public void preThreading(LocalClassPass.ThreadingWalker walker) { 1289 walker.pushNonConstructorEnv(); 1290 walker.pushTypeDec(this); 1291 } 1292 1293 public ASTObject postThreading(LocalClassPass.ThreadingWalker walker) { 1294 walker.popTypeDec(); 1295 walker.popEnv(); 1296 return this; 1297 } 1298 1299 1302 protected void cgMember(ClassfileBuilder maker) { 1303 maker.delayInnerClassGeneration(this); 1304 } 1305 1306 1309 public File getPackageDir(File outputdir) { 1310 String packagename = getPackageName(); 1311 if (getOptions().XtargetNearSource && (outputdir == Options.getDefaultOutputDir())) { 1312 return new File(getSourceDirectoryName()); 1313 } 1314 1316 if (packagename == null) return outputdir; 1317 1318 int lastDot = 0; 1319 int dot = 0; 1320 while ((dot = packagename.indexOf('.', lastDot)) != -1) { 1321 outputdir = new File(outputdir, packagename.substring(lastDot, dot)); 1322 lastDot = dot+1; 1323 } 1324 return new File(outputdir, packagename.substring(lastDot)); 1325 } 1326 1327 1328 1330 public final void generateBytecode(File outputDir) throws IOException { 1331 String filename = getExtendedId()+".class"; 1332 getCompiler().showMessage(" writing " + filename); 1333 1334 getCompiler().beginSection("bcg:AST-directed"); 1335 ClassfileBuilder cfb = new ClassfileBuilder(getCompiler()); 1337 cfb.setSourceFile(getSourceLocation()); 1338 if (!this.isConcrete()) getModifiers().setInterface(true); 1339 cfb.addAccessFlags(getModifiers().getAcceptableClassValue()); 1340 1341 cfb.setClassName((NameType)getType()); 1342 cfb.setSuperClassName((NameType)getSuperClassType()); 1343 for (Iterator i = getSuperInterfaceTypes().iterator(); i.hasNext(); ) { 1344 NameType iface = (NameType)i.next(); 1345 cfb.addInterface(iface); 1346 } 1347 for (Iterator i = getBody().iterator(); i.hasNext(); ) { 1348 Dec memberDec = (Dec)i.next(); 1349 memberDec.cgMember(cfb); 1350 } 1351 1354 getCompiler().beginSection("bcg:assembly"); 1356 cfb.resolve(); 1357 1359 getCompiler().beginSection("bcg:output"); 1361 File packagedir = getPackageDir(outputDir); 1362 packagedir.mkdirs(); 1363 File outFile = new File(packagedir, filename); 1364 FileOutputStream fileStream = new FileOutputStream(outFile); 1365 DataOutputStream stream = 1366 new DataOutputStream(new BufferedOutputStream(fileStream)); 1367 cfb.writeTo(stream); 1368 stream.close(); 1369 1371 cfb.generateBytecodeForDelayedInnerClasses(outputDir); 1372 } 1373 1374 protected Modifiers modifiers; 1376 public Modifiers getModifiers() { return modifiers; } 1377 public void setModifiers(Modifiers _modifiers) { 1378 if (_modifiers != null) _modifiers.setParent(this); 1379 modifiers = _modifiers; 1380 } 1381 1382 protected String id; 1383 public String getId() { return id; } 1384 public void setId(String _id) { id = _id; } 1385 1386 protected TypeDs superInterfaces; 1387 public TypeDs getSuperInterfaces() { return superInterfaces; } 1388 public void setSuperInterfaces(TypeDs _superInterfaces) { 1389 if (_superInterfaces != null) _superInterfaces.setParent(this); 1390 superInterfaces = _superInterfaces; 1391 } 1392 1393 protected Decs body; 1394 public Decs getBody() { return body; } 1395 public void setBody(Decs _body) { 1396 if (_body != null) _body.setParent(this); 1397 body = _body; 1398 } 1399 1400 public TypeDec(SourceLocation location, Modifiers _modifiers, String _id, TypeDs _superInterfaces, Decs _body) { 1401 super(location); 1402 setModifiers(_modifiers); 1403 setId(_id); 1404 setSuperInterfaces(_superInterfaces); 1405 setBody(_body); 1406 } 1407 protected TypeDec(SourceLocation source) { 1408 super(source); 1409 } 1410 1411 public ASTObject getChildAt(int childIndex) { 1412 switch(childIndex) { 1413 case 0: return modifiers; 1414 case 1: return superInterfaces; 1415 case 2: return body; 1416 default: return super.getChildAt(childIndex); 1417 } 1418 } 1419 public String getChildNameAt(int childIndex) { 1420 switch(childIndex) { 1421 case 0: return "modifiers"; 1422 case 1: return "superInterfaces"; 1423 case 2: return "body"; 1424 default: return super.getChildNameAt(childIndex); 1425 } 1426 } 1427 public void setChildAt(int childIndex, ASTObject child) { 1428 switch(childIndex) { 1429 case 0: setModifiers((Modifiers)child); return; 1430 case 1: setSuperInterfaces((TypeDs)child); return; 1431 case 2: setBody((Decs)child); return; 1432 default: super.setChildAt(childIndex, child); return; 1433 } 1434 } 1435 public int getChildCount() { 1436 return 3; 1437 } 1438 1439 public String getDefaultDisplayName() { 1440 return "TypeDec(id: "+id+")"; 1441 } 1442 1443 } 1445 | Popular Tags |