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.crosscuts.*; 32 33 import java.util.*; 34 import java.io.IOException ; 35 36 public abstract class ASTObject extends CompilerObject { 37 protected SourceLocation sourceLocation = null; 38 protected ASTObject parent; 39 40 public ASTObject(SourceLocation loc) { 41 super(loc.getCompiler()); 42 this.sourceLocation = loc; 43 } 44 45 public boolean hasSourceLocation() { 46 return sourceLocation != null; 47 } 48 49 public SourceLocation getSourceLocation() { 50 return sourceLocation; 51 } 52 public void setSourceLocation(SourceLocation newLocation) { 53 sourceLocation = newLocation; 54 } 55 56 public int getStartPosition() { return getSourceLocation().getStartPosition(); } 57 public int getEndPosition() { return getSourceLocation().getEndPosition(); } 58 public int getBeginLine() { return getSourceLocation().getBeginLine(); } 59 public int getEndLine() { return getSourceLocation().getEndLine(); } 60 public int getBeginColumn() { return getSourceLocation().getBeginColumn(); } 61 public int getEndColumn() { return getSourceLocation().getBeginLine(); } 62 63 public Comment getComment() { 64 return getSourceLocation().getComment(); 65 } 66 67 public void addComment(Comment _comment) { 68 getSourceLocation().addComment(_comment); 69 } 70 71 public boolean isSynthetic() { 72 return getSourceLocation().isSynthetic(); 73 } 74 public boolean isLanguageVisible() { 75 return !getSourceLocation().isSynthetic(); 76 } 77 78 79 public void setFormalComment(String comment) { 80 getSourceLocation().setFormalComment(comment); 81 } 82 83 public String getFormalComment() { 84 return getSourceLocation().getFormalComment(); 85 } 86 87 public void clearComment() { 88 getSourceLocation().clearComment(); 89 } 90 91 public CompilationUnit getCompilationUnit() { 92 return getSourceLocation().getCompilationUnit(); 93 } 94 95 public java.io.File getSourceFile() { 96 return getSourceLocation().getSourceFile(); 97 } 98 99 final public String getSourceFileName() { 100 return getSourceLocation().getSourceFileName(); 101 } 102 103 final public String getSourceDirectoryName() { 104 return getSourceLocation().getSourceDirectoryName(); 105 } 106 107 108 public boolean hasSource() { 109 return getSourceLocation().hasSource(); 110 } 111 112 public boolean fromSource() { 113 return getSourceLocation().fromSource(); 114 } 115 116 117 public void setParent(ASTObject x) { 119 if (getOptions().strictTree && parent != null && parent != x) { 121 this.showError("changing parent from " + parent + " to " + x); 122 } 123 parent = x; 124 } 125 126 127 public ASTObject getParent() { return parent; } 129 130 public int getChildCount() { return 0; } 131 132 public ASTObject getChildAt(int childIndex) { return null; } 134 public String getChildNameAt(int childIndex) { return null; } 135 public void setChildAt(int childIndex, ASTObject child) {} 136 public void removeChildAt(int childIndex) { 137 remove(childIndex); 138 } 139 140 public void remove(int index) { 141 setChildAt(index, null); 143 } 145 146 public void remove(ASTObject child) { 147 int index = indexOf(child); 148 if (index == -1) { 149 throw new IllegalArgumentException ("not a child"); 150 } 151 remove(index); 152 } 153 154 155 public boolean isLeaf() { 156 return getChildCount() == 0; 157 } 158 159 public int indexOf(ASTObject node) { 160 int n = getChildCount(); 161 for(int i=0; i<n; i++) { 162 ASTObject child = getChildAt(i); 164 165 if (child != null && child == node) return i; } 167 return -1; 168 } 169 170 public boolean contains(ASTObject node) { 171 return indexOf(node) != -1; 172 } 173 174 public boolean hasLegalProtectedAccess(Type fromType) { 176 return true; 178 } 179 180 public final boolean containsTypes() { 181 if (this instanceof TypeDec) return true; 182 183 for(int i=0, n=getChildCount(); i<n; i++) { 184 ASTObject child = getChildAt(i); 185 if (child != null && child.containsTypes()) return true; 186 } 187 return false; 188 } 189 190 193 public void walkForwardReference(ForwardReferenceChecker w) { 194 this.walk(w); 195 } 196 197 200 public void walkFlow(FlowCheckerPass w) { 201 this.walk(w); 202 } 203 204 207 public void walkFrameLoc(FrameLocPass walker) { 208 this.walk(walker); 209 } 210 211 212 213 public void preMove(MovingWalker walker) { 215 } 216 217 public ASTObject postMove(MovingWalker walker) { 218 return this; 219 } 220 221 public ASTObject fixAccessPost(org.aspectj.compiler.crosscuts.AccessFixer fixer) { 223 return this; 224 } 225 226 public ASTObject copyWalk(CopyWalker walker) { return null; } 228 public ASTObject postCopy(CopyWalker walker, ASTObject oldObject) { 229 return this; 230 } 231 public void preCopy(CopyWalker walker, ASTObject oldObject) { } 232 233 public void preIntroduction(IntroductionPlannerPass pass) { } 235 236 public void preScope(ScopeWalker walker) { } 238 public ASTObject postScope(ScopeWalker walker) { return this; } 239 public void walkScope(ScopeWalker walker) { walk(walker); } 240 241 242 public void walk(Walker walker) { 243 for(int i=0; i<getChildCount(); i++) { 245 258 ASTObject child = getChildAt(i); 259 if (child != null) { 260 if (getOptions().strictTree && child.getParent() != this) { 261 child.showError("wrong parent: " + this.unparse() + " '" + child.unparse() + "'"); 262 System.out.println(child.getParent().unparse()); 263 } 264 ASTObject newChild = walker.process(child); 265 if (newChild == child) continue; 266 if (newChild == null) { 267 removeChildAt(i); 268 i -= 1; 270 } else { 272 setChildAt(i, newChild); 273 } 274 } 275 } 276 } 277 278 public Type getOutermostLexicalType() { 279 if (parent == null) return getTypeManager().TYPE_NOT_FOUND; 280 return parent.getOutermostLexicalType(); 281 } 282 283 public Type getOutermostBytecodeType() { 284 if (parent == null) return getTypeManager().TYPE_NOT_FOUND; 285 286 return parent.getOutermostBytecodeType(); 287 } 288 289 307 308 309 public Type getLexicalType() { 310 if (getParent() == null) { 312 return null; 314 } 315 if (this instanceof Decs && getParent() instanceof TypeDec) return ((TypeDec)getParent()).getType(); 316 return getParent().getLexicalType(); 317 } 318 319 328 329 public Type getDeclaringType() { 330 if (getParent() == null) { 331 return null; 333 } 334 if (getParent() instanceof TypeDec) return ((TypeDec)getParent()).getType(); 335 return getParent().getDeclaringType(); 336 } 337 338 344 public TypeDec getBytecodeTypeDec() { 345 if (getParent() == null) { 346 showError("no parent: " + this + ": " + System.identityHashCode(this)); 347 System.out.println(unparse()); 348 return getTypeManager().TYPE_DEC_NOT_FOUND; } 350 if (getParent() instanceof TypeDec) return (TypeDec)getParent(); 351 return getParent().getBytecodeTypeDec(); 352 } 353 354 355 public Type getBytecodeType() { 356 TypeDec dec = getBytecodeTypeDec(); 357 if (dec == null) return null; 358 return dec.getType(); 359 } 360 361 public Dec getEnclosingDec() { 362 if (getParent() == null) { 363 return null; 366 } 367 return getParent().getEnclosingDec(); 368 } 369 370 public CodeDec getEnclosingCodeDec() { 371 if (getParent() == null) { 372 return null; 375 } 376 return getParent().getEnclosingCodeDec(); 377 } 378 379 380 381 public boolean inStaticContext() { 382 if (getParent() == null) return true; 383 return getParent().inStaticContext(); 384 } 385 386 public void showTypeError(Type foundType, Type requiredType) { 387 if (foundType.isMissing() || requiredType.isMissing()) return; 388 showError("incompatible types\n" + 389 "found : " + foundType.getString() + "\n" + 390 "required: " + requiredType.getString()); 391 } 392 public void showError(String message) { 393 getCompiler().showError(this,message); 394 } 395 public void showWarning(String message) { 396 getCompiler().showWarning(this,message); 397 } 398 public void showMessage(String message) { 400 getCompiler().showMessage(this,message); 401 } 402 403 public String toShortString() { 404 return this.getClass().getName(); 405 } 406 407 public ASTObject copy() { return CopyWalker.copy(this); } 408 409 410 public void checkNoSharing(ASTObject other) { 411 Set s1 = new HashSet(); 412 Set s2 = new HashSet(); 413 this.addContainedNodes(s1); 414 other.addContainedNodes(s2); 415 416 s1.retainAll(s2); 417 if (!s1.isEmpty()) { 418 getCompiler().showError(this, "shares nodes with " + other + "\n" + 419 s1); 420 } 421 } 422 423 428 private void addContainedNodes(Set ret) { 429 if (ret.contains(this)) { 430 getCompiler().showError(this, "duplicate node in " + ret); 431 } 432 ret.add(this); 433 for(int i=0; i<getChildCount(); i++) { 434 ASTObject o = getChildAt(i); 435 if (o != null) o.addContainedNodes(ret); 436 } 437 } 438 439 444 public ASTObject setSource(ASTObject sourceObject) { 445 sourceLocation = sourceObject.sourceLocation; 446 return this; 447 } 448 449 452 public ASTObject setSyntheticSource(ASTObject sourceObject) { 453 sourceLocation = new SourceSourceLocation(sourceObject); 454 return this; 455 } 456 457 protected void makeChild(ASTObject object) { 458 if (object != null) object.parent = this; 459 } 460 461 protected void makeChild(ASTObject[] array) { 462 if (array == null) return; 463 int n = array.length; 464 for(int i=0; i<n; i++) { 465 makeChild(array[i]); 466 } 467 } 468 469 public String getDefaultDisplayName() { 470 return this.getClass().getName(); 471 } 472 473 public void clearParent() { parent = null; } 474 475 protected void setParents() {} 476 477 public void replaceWith(ASTObject other) { 478 ASTObject parent = getParent(); 479 if (parent == null) { 480 showWarning("no parent to replace in"); 481 display(2); 482 return; 483 } 484 int i = parent.indexOf(this); 485 if (i == -1) { 486 showError("invalid replacement attempt, not in: " + parent); 487 parent.display(2); 488 return; 489 } 490 parent.setChildAt(i, other); 492 } 493 494 public String toString() { 495 return getDefaultDisplayName(); } 497 498 public void display(int indent) { 499 for(int s=0; s<indent; s++) System.out.print(" "); 500 System.out.println(getDefaultDisplayName() + System.identityHashCode(this)); 502 final int N = getChildCount(); 503 for(int i=0; i<N; i++) { 504 ASTObject child = getChildAt(i); 505 if (child != null) { 506 child.display(indent+1); 507 } 508 } 509 } 510 511 public AST getAST() { 512 return new AST(new SourceSourceLocation(this)); 514 } 515 516 public String unparse() { 517 CodeWriter writer = new CodeWriter(getCompiler()); 518 writer.write(this); 519 return writer.getString(); 520 } 521 522 public void unparse(CodeWriter writer) throws IOException { 524 writer.write("/* "); 525 writer.write(getDefaultDisplayName()); 526 writer.write(" */"); 527 writer.newLine(); 528 } 529 530 public void cleanup() { 531 } 532 533 public void fixAST(ASTFixerPass fixer) { this.walk(fixer); } 535 public ASTObject postFixAST(ASTFixerPass fixer) { return this; } 536 537 public void implementMixin(MixinImplementationPass walker) { this.walk(walker); } 539 public ASTObject postImplementMixin(MixinImplementationPass walker) { return this; } 540 541 544 public void walkInnerInfo(InnerInfoPass walker) { 545 this.walk(walker); 546 } 547 public void postInnerInfo(InnerInfoPass walker) { } 548 549 552 public void checkSpec() { } 553 554 557 public void preAssignmentCheck(AssignmentCheckerPass walker) { } 558 public void walkAssignmentCheck(AssignmentCheckerPass walker) { 559 this.walk(walker); 560 } 561 public ASTObject postAssignmentCheck(AssignmentCheckerPass walker) { 562 return this; 563 } 564 565 568 public void walkAnalysis(LocalClassPass.AnalysisWalker walker) { 569 walk(walker); 570 } 571 public void preLift(LocalClassPass.LiftWalker walker) {} 572 public ASTObject postLift(LocalClassPass.LiftWalker walker) { 573 return this; 574 } 575 public void preThreading(LocalClassPass.ThreadingWalker walker) {} 576 public ASTObject postThreading(LocalClassPass.ThreadingWalker walker) { 577 return this; 578 } 579 580 583 public ASTObject walkMemberMunger(MemberClassMunger w) { 584 this.walk(w); 585 return this; 586 } 587 588 591 593 public ASTObject postInnerAccess(InnerAccessFixer w) { 594 return this; 595 } 596 597 608 public MethodDec buildAccessMethod(InnerAccessFixer w) { 609 throw new RuntimeException ("No access method should be built for " + this); 610 } 611 612 615 public void walkCleanup(ByteCodeCleanupPass walker) { 616 this.walk(walker); 617 } 618 public ASTObject postCleanup(ByteCodeCleanupPass walker) { 619 return this; 620 } 621 } 622 | Popular Tags |