1 24 25 package org.aspectj.compiler.base.ast; 26 27 import java.util.*; 28 29 import org.aspectj.compiler.base.bcg.CodeBuilder; 30 import org.aspectj.compiler.base.*; 31 import java.io.IOException ; 32 33 import org.aspectj.compiler.crosscuts.ast.*; 35 import org.aspectj.compiler.crosscuts.joinpoints.*; 36 37 38 46 public class NameType extends org.aspectj.compiler.base.ast.RefType { 47 final SemanticMap fields = new SemanticMap(this, "field"); 48 49 final SemanticMap pointcuts = new SemanticMap(this, "pointcut"); 50 51 final SemanticMap innerTypes = new SemanticMap(this, "type"); 52 53 final SemanticMap methods = new SemanticMap(this, "method"); 54 55 final SemanticMap constructors = new SemanticMap(this, "constructor"); 58 59 public NameType(TypeDec typeDec) { 60 super(typeDec.getCompiler()); 61 this.dec = typeDec; 62 } 63 64 public TypeDec getTypeDec() { return (TypeDec)dec; } 65 66 public boolean isCoercableTo(Type other) { 67 if (this.isAssignableFrom(other)) return true; 68 if (other.isAssignableFrom(this)) return true; 69 70 if (! (other instanceof NameType) ) return false; 71 72 if (!isInterface() && !other.isInterface()) return false; 74 75 if (isInterface() && other.isInterface()) { 77 return methodsCompatibleWith(other); 78 } 79 80 if (isInterface()) return !((NameType)other).isFinal(); 85 if (other.isInterface()) return !this.isFinal(); 86 87 return false; 88 } 89 90 91 95 private boolean methodsCompatibleWith(Type other) { 96 for (Iterator i = getMethods().iterator(); i.hasNext(); ) { 97 Method m = (Method)i.next(); 98 Method mOther = (Method)other.findMatchingSemanticObject(m); 99 if (mOther != null) { 100 if (!m.getReturnType().isEquivalent(mOther.getReturnType())) { 101 return false; 102 } 103 } 104 } 105 return true; 106 } 107 108 109 public boolean dominates(Type other) { 110 TypeDec t1 = getTypeDec(); 111 TypeDec t2 = other.getTypeDec(); 112 if (t2 != null && t1 instanceof AspectDec && t2 instanceof AspectDec) { 113 return ((AspectDec)t1).dominates((AspectDec)t2); 114 } else { 115 return super.dominates(other); 116 } 117 } 118 119 public boolean isEffectivelyStatic() { 120 return isStatic() || isPackageMember(); 121 } 122 123 public Expr getClassExpr() { 124 if (! getTypeDec().hasGlobalName()) return getAST().makeNull(); 125 return new ClassExpr(getAST().getSourceLocation(), this.makeTypeD()); 126 } 127 128 public Expr makeObject(Expr expr) { return expr; } 129 130 public Expr fromObject(Expr expr) { 131 return getAST().makeCast(this, expr); 132 } 133 134 public Expr getNullExpr() { 135 return getAST().makeNull(); 136 } 137 138 public Type getRefType() { return this; } 139 140 public Type getOutermostType() { 141 return getTypeDec().getOutermostType(); 142 } 143 144 145 public PointcutSO getPointcut(String id, ASTObject fromWhere, boolean showError) { 146 ensureFinishedSignature(); 147 return (PointcutSO)pointcuts.get(id, fromWhere, null, showError); 148 } 149 150 public Field getField(String id, ASTObject fromWhere, boolean showError) { 151 ensureFinishedSignature(); 153 return (Field)fields.get(id, fromWhere, null, showError); 154 } 155 156 public Type getInnerType(String id, ASTObject fromWhere, boolean showError) { 157 ensureBuiltTypeGraph(); 161 Type ret = (Type)innerTypes.get(id, fromWhere, null, showError); 163 return ret; 165 } 166 167 public Method getMethod(String id, ASTObject fromWhere, Exprs params, boolean showError) { 168 ensureFinishedSignature(); 169 Method ret = (Method)methods.get(id, fromWhere, params, showError); 171 return ret; 176 } 177 178 public boolean hasMethodNamed(String id) { 180 ensureFinishedSignature(); 181 return methods.hasName(id); 182 } 183 184 public Constructor getConstructor(ASTObject fromWhere, Exprs params, boolean showError) { 185 ensureFinishedSignature(); 186 187 return (Constructor)constructors.get("new", fromWhere, params, showError); 188 } 189 190 public SemanticObject findMatchingSemanticObject(SemanticObject o) { 191 if (o instanceof Method) { 192 return methods.findMatchingSemanticObject(o); 193 } else if (o instanceof Constructor) { 194 return constructors.findMatchingSemanticObject(o); 195 } else if (o instanceof Field) { 196 return fields.findMatchingSemanticObject(o); 197 } else { 198 return null; 199 } 200 } 201 202 private void addInheritedMembers(SemanticMap map, Collection bag) { 203 for (Iterator i = map.getAllSemanticObjects().iterator(); i.hasNext(); ) { 204 SemanticObject so = (SemanticObject)i.next(); 205 if (so.getDeclaringType() != this) { bag.add(so); } 206 } 207 } 208 209 public Collection getInheritedMethods() { 211 List ret = new LinkedList(); 212 addInheritedMembers(methods, ret); 213 return ret; 214 } 215 216 public Collection getInheritedMembers() { 217 List ret = new LinkedList(); 218 addInheritedMembers(methods, ret); 219 addInheritedMembers(innerTypes, ret); 220 addInheritedMembers(fields, ret); 221 addInheritedMembers(pointcuts, ret); 222 return ret; 223 } 224 225 public Collection getConstructors() { 226 return constructors.getAllSemanticObjects(); 227 } 228 229 230 public Collection getMethods() { 231 return methods.getAllSemanticObjects(); 232 } 233 234 public Collection getFields() { 235 return fields.getAllSemanticObjects(); 236 } 237 238 public Collection getPointcuts() { 239 return pointcuts.getAllSemanticObjects(); 240 } 241 242 243 public void addPointcut(PointcutDec pointcut) { 244 pointcuts.addDeclared(pointcut.getCorrespondingSemanticObject()); 245 } 246 247 public void addField(FieldDec field) { 248 fields.addDeclared(field.getCorrespondingSemanticObject()); 250 } 251 252 public void addMethod(MethodDec method) { 253 methods.addDeclared(method.getCorrespondingSemanticObject()); 254 } 255 256 public void addConstructor(ConstructorDec constructor) { 257 constructors.addDeclared(constructor.getCorrespondingSemanticObject()); 258 } 259 260 public NameType getSuperClassType() { 261 return (NameType)getTypeDec().getSuperClassType(); 262 } 263 264 public Type getDeclaringType() { 265 return getTypeDec().getDeclaringType(); 266 } 267 268 public void addInnerType(TypeDec type) { 269 innerTypes.addDeclared(type.getType()); 271 } 272 273 public Collection getInheritedFromTypes() { 274 return directSuperTypes; 276 } 277 278 private void initializeInheritedTypeMap() { 279 for (Iterator i = getInheritedFromTypes().iterator(); i.hasNext(); ) { 280 NameType superType = (NameType)i.next(); 281 superType.ensureBuiltTypeGraph(); 282 innerTypes.addInherited(superType.innerTypes); 283 } 284 285 } 289 290 291 private void handleInheritedMembers(NameType superType) { 292 superType.ensureFinishedSignature(); 293 294 pointcuts.addInherited(superType.pointcuts); 295 fields.addInherited(superType.fields); 296 methods.addInherited(superType.methods); 297 } 298 299 private void handleInheritedMembers() { 300 NameType superClassType = getSuperClassType(); 301 if (superClassType != null && getInheritedFromTypes().contains(superClassType)) { 303 handleInheritedMembers(superClassType); 305 } 306 307 for (Iterator i = getInheritedFromTypes().iterator(); i.hasNext(); ) { 308 NameType superType = (NameType)i.next(); 309 if (superType != superClassType) handleInheritedMembers(superType); 310 } 311 } 312 313 public String getPrettyString() { 315 String prettyString = null; 316 if (prettyString != null) return prettyString; 317 318 prettyString = getLegalString().replace('$', '.'); 323 325 return prettyString; 326 } 327 328 private String makeLegalString() { 329 return getTypeDec().getFullName(); 330 } 339 340 public String getLegalString() { 342 return makeLegalString(); 343 } 347 348 public String getSourceString() { 349 TypeDec typeDec = getTypeDec(); 350 return getPrettyString(); 354 } 355 356 public String getString() { 358 return getSourceString(); } 360 361 362 369 public String getExtendedId() { 370 return getTypeDec().getExtendedId(); 371 } 372 373 374 379 public String getId() { 380 return getTypeDec().getId(); 381 } 382 383 public String getExternalName() { 384 return getClassName(); 385 } 386 387 public String getClassName() { 388 return getTypeDec().getFullName(); 389 } 390 391 public String getPackageName() { 392 return getTypeDec().getPackageName(); 393 } 394 395 396 public void unparse(CodeWriter writer) throws IOException { 397 writer.write(getSourceString()); 398 } 399 400 404 public String toShortString() { 405 String ret = getTypeDec().getSourceExtendedId(); 406 return ret; 408 } 409 410 public String toString() { 411 return "NameType("+getPrettyString()+")"; 412 } 413 414 415 public boolean isInterface() { return getTypeDec() instanceof InterfaceDec; } 416 public boolean isClass() { return getTypeDec() instanceof ClassDec; } 417 public boolean isAspect() { return getTypeDec() instanceof AspectDec; } 418 419 public boolean isInnerType() { return getTypeDec().isInnerType(); } 420 421 public boolean isAnonymous() { return getTypeDec().isLocallyDefined(); } 422 423 public boolean isAbstract() { return isInterface() || getTypeDec().isAbstract(); } 424 public boolean isFinal() { return getTypeDec().isFinal(); } 425 426 public void ensureNoAbstractDecs() { 427 pointcuts.ensureNoAbstracts(); 428 methods.ensureNoAbstracts(); 429 } 430 431 432 synchronized public void ensureBuiltTypeGraph() { 433 if (builtTypeGraph) return; 434 getTypeDec().addToTypeGraph(); } 440 441 synchronized public void ensureFinishedSignature() { 442 if (builtSignatures) return; 443 451 ensureBuiltTypeGraph(); 452 getTypeDec().buildSignatures(); } 455 456 479 private boolean builtTypeGraph = false; 480 public void addToTypeGraph() { 481 if (builtTypeGraph) { 482 getCompiler().internalError("already built type graph " + 483 getPrettyString()); 484 return; 485 } 486 builtTypeGraph = true; 487 getCompiler().showMessage(" building type graph " + getPrettyString()); 488 489 if (this != getTypeManager().getObjectType()) { 490 addDirectSuperType(getTypeDec().getSuperClassType()); 491 } 492 493 for (Iterator i = getTypeDec().getSuperInterfaceTypes().iterator(); 494 i.hasNext(); ) 495 { 496 NameType superInterfaceType = (NameType)i.next(); 497 addDirectSuperType(superInterfaceType); 498 } 499 500 initializeInheritedTypeMap(); 501 502 getTypeDec().addInnerTypes(); 503 } 504 505 private boolean builtSignatures = false; 506 public void buildSignatures() { 507 if (builtSignatures) { 508 getCompiler().internalError("already built signatures: " + 509 getPrettyString()); 510 return; 511 } 512 builtSignatures = true; 513 getCompiler().showMessage(" building signatures " + getPrettyString()); 514 515 if (getTypeDec().fromSource()) checkForCircularities(); 516 517 getWorld().runTypeDecPlanners(getTypeDec(), TypeDecPlanner.TYPE); 518 519 getTypeDec().addDecs(this); 520 521 getWorld().runTypeDecPlanners(getTypeDec(), TypeDecPlanner.SIGNATURE); 522 524 handleInheritedMembers(); 525 } 526 527 public Collection getInnerTypes() { 528 return innerTypes.getAllSemanticObjects(); 529 } 530 531 public Type getOutermostLexicalType() { 532 return getTypeDec().getOutermostLexicalType(); 533 } 534 535 public Type getOutermostBytecodeType() { 536 return getTypeDec().getOutermostBytecodeType(); 537 } 538 539 540 541 542 private boolean isLazy = true; 544 public void setLazy() { isLazy = true; } 545 546 547 public void checkForCircularities() { 548 checkForCircularities(new LinkedList()); 549 } 550 551 private boolean checkForCircularities(LinkedList list) { 552 if (list.contains(this)) { 553 StringBuffer message = new StringBuffer ("cyclic inheritance, "); 554 boolean foundThis = false; 555 for (Iterator i = list.iterator(); i.hasNext(); ) { 556 Type t = (Type)i.next(); 557 if (t == this) { 558 foundThis = true; 559 } 560 if (foundThis) { 561 message.append(t.getString()); 562 message.append(" -> "); 563 } 564 } 565 message.append(getString()); 566 getTypeDec().showError(message.toString()); 574 directSuperTypes.clear(); 576 return true; 577 } else { 578 list.add(this); 579 if (getEnclosingType() != null) { 580 if (getEnclosingType().checkForCircularities(list)) return true; 581 } 582 583 for (Iterator i = directSuperTypes.iterator(); i.hasNext(); ) { 584 NameType superType = (NameType)i.next(); 585 if (superType.checkForCircularities(list)) return true; 586 } 587 list.removeLast(); 588 return false; 589 } 590 } 591 592 private String internalName; 595 private String descriptor; 596 597 public synchronized String getInternalName() { 598 if (internalName == null) { 599 internalName = getClassName().replace('.', '/'); 600 } 601 return internalName; 602 } 603 604 public synchronized String getDescriptor() { 605 if (descriptor == null) { 606 descriptor = "L" + getInternalName() + ";"; 607 } 608 return descriptor; 609 } 610 611 final LiteralExpr foldAddOp(LiteralExpr rand1, LiteralExpr rand2) { 614 return getAST().makeLiteral(rand1.getStringValue() + rand2.getStringValue()); 615 } 616 final LiteralExpr foldEqualityTestOp(String op, LiteralExpr lit1, LiteralExpr lit2) { 617 final AST ast = getAST(); 618 String a = lit1.getStringValue(); 619 String b = lit2.getStringValue(); 620 if (op == "==") return ast.makeLiteral(a.equals(b)); 621 else if (op == "!=") return ast.makeLiteral(! a.equals(b)); 622 else throw new RuntimeException ("bad op " + op); 623 } 624 final LiteralExpr foldCast(LiteralExpr lit) { 625 return getAST().makeLiteral(lit.getStringValue()); 626 } 627 628 631 639 public boolean isInner() { 640 return getTypeDec().isInner(); 641 } 642 public NameType getEnclosingInstanceType() { 643 return (NameType)getDeclaringType(); 645 } 646 647 public boolean isLocal() { 648 TypeDec typeDec = getTypeDec(); 649 if (typeDec == null) return false; return typeDec.isLocal(); 651 } 652 public CodeDec getEnclosingCodeDec() { 653 return getTypeDec().getEnclosingCodeDec(); 655 } 656 657 public boolean isPackageMember() { 658 return getTypeDec().isPackageMember(); 659 } 660 public NameType getEnclosingType() { 661 return (NameType)getDeclaringType(); 663 } 664 } 665 | Popular Tags |