1 24 25 package org.aspectj.compiler.crosscuts.joinpoints; 26 27 import org.aspectj.compiler.base.ast.*; 28 import org.aspectj.compiler.base.*; 29 import org.aspectj.compiler.crosscuts.ast.*; 30 import org.aspectj.compiler.crosscuts.AspectJCompiler; 31 import org.aspectj.util.PartialOrder; 32 33 import java.util.*; 34 35 40 public abstract class JoinPoint extends CompilerObject { 41 public final static int METHOD_EXECUTION = 0X001; 42 public final static int METHOD_CALL = 0x004; 44 public final static int CONSTRUCTOR_EXECUTION = 0x008; 45 public final static int CONSTRUCTOR_CALL = 0x020; 47 public final static int FIELD_GET = 0x040; 48 public final static int FIELD_SET = 0x080; 49 public final static int HANDLER = 0x100; 50 51 public final static int ADVICE_EXECUTION = 0x1000; 52 public final static int STATIC_INITIALIZER_EXECUTION = 0x2000; 53 public final static int INSTANCE_INITIALIZER_EXECUTION = 0x4000; 54 public final static int INITIALIZER_EXECUTION = 0x8000; 55 56 public final static int SUPER_METHOD_CALL = 0x10000; 57 public final static int SUPER_CONSTRUCTOR_CALL = 0x20000; 58 59 public static class Kind { 60 private String name; 61 private int id; 62 63 public Kind(String name, int id) { 64 this.name = name; 65 this.id = id; 66 } 67 68 public int getIntCode() { 69 return id; 70 } 71 public String toString() { 72 return name; 73 } 74 public String toFullString() { 75 return name; 76 } 77 public String toShortString() { 78 return name; 79 } 80 } 81 82 public abstract Kind getKind(); 83 84 List plans 86 = new ArrayList(0); 87 private boolean implementedPlans = false; 88 89 private VarDec dynamicJoinPointDec = null; 90 private FieldDec staticJoinPointDec = null; 91 92 public JoinPoint(JavaCompiler compiler) { 93 super(compiler); 94 } 95 96 public void addPlan(JpPlan plan) { 97 plans.add(plan); 99 } 100 101 104 public abstract ASTObject getSourceLocation(); 105 106 public abstract Dec getTargetDec(); public SemanticObject getTargetSO() { 109 return getTargetDec().getCorrespondingSemanticObject(); 110 } 111 public ASTObject getTargetNode() { 113 return getSourceLocation(); 114 } 115 116 public final int getTypeCode() { 118 return getKind().getIntCode(); 119 } 120 121 public abstract Type getResultType(); 122 123 public Type getExceptionType() { 124 return null; 125 } 126 127 public Type getBytecodeType() { 128 return getSourceLocation().getBytecodeType(); 129 } 130 131 public Type getDeclaringType() { 132 return getSourceLocation().getDeclaringType(); 133 } 134 135 public abstract Type getTargetType(); 136 137 public Set getTargetTypes() { 138 Set ret = new HashSet(); 139 Type t = getTargetType(); 140 if (t == null) { 141 getCompiler().internalError("must override getTargetTypes in " + this); 142 } else { 143 ret.add(t); 144 } 145 return ret; 146 } 147 148 152 public Type getTargetExprType() { 153 return getThisExprType(); 154 } 155 156 160 public Expr makeTargetExpr() { 161 return makeThisExpr(); 162 } 163 164 167 public Type getThisExprType() { 168 if (isStaticContext()) 169 return null; 170 else 171 return getDeclaringType(); 172 } 173 174 public abstract boolean isStaticContext(); 175 176 179 public Expr makeThisExpr() { 180 Type thisType = getThisExprType(); 181 if (thisType == null) 182 return null; 183 else 184 return getAST().makeThis(thisType); 185 } 186 187 190 193 196 public abstract Exprs makeArgsExprs(); 197 198 199 public Expr makeThisExprOrType() { 200 if (isStaticContext()) { 201 return getAST().makeTypeExpr(getBytecodeType()); 202 } else { 203 return getAST().makeThis(getBytecodeType()); 204 } 205 } 206 207 public Expr makeVoidReturnExpr() { 208 return getAST().makeNull(); 209 } 210 211 public abstract boolean canThrow(Type t); 212 public abstract Collection getPossibleCheckedExceptions(); 213 214 public void showError(ASTObject node, String message) { 215 node.showError("on target " + this +" " + message); 217 218 if (plans.size() > 0) { 219 JpPlan plan = (JpPlan)plans.get(0); 220 if (plan instanceof AdvicePlan) { 221 AdviceDec adviceDec = ((AdvicePlan)plan).getAdviceDec(); 222 if (adviceDec == node || adviceDec.getPcd() == node) { 223 return; 224 } 225 ASTObject where = adviceDec.getPcd(); 226 where.showError("above target " + this + " is matched by"); 227 } 228 } 229 } 230 231 public void showWarning(ASTObject node, String message) { 232 node.showWarning("on target " + this +" " + message); 234 } 235 236 239 public Type makeFactoryType() { 240 return getTypeManager().getType("org.aspectj.runtime.reflect", "Factory"); 241 } 242 243 public FieldDec makeFactoryDec() { 244 final AST ast = getAST(); 245 246 java.io.File f = getStaticFieldHolder().getSourceFile(); 247 String fname; 248 if (f == null) 249 fname = "<missing>"; 250 else 251 fname = f.getName(); 252 253 Modifiers modifiers = ast.makeModifiers(Modifiers.STATIC | Modifiers.FINAL); 254 if (getStaticFieldHolder().getType().isInterface()) 255 modifiers.setPublic(true); 256 257 return ast.makeField( 258 modifiers, 259 makeFactoryType(), 260 "ajc$JPF", 261 ast.makeNew( 262 makeFactoryType(), 263 ast.makeLiteral(fname), 264 ast.makeLiteral(getStaticFieldHolder().getType()))); 265 } 266 267 public FieldDec getFactoryDec() { 268 if (getStaticFieldHolder().joinPointFactoryDec == null) { 269 FieldDec factoryDec = makeFactoryDec(); 270 getStaticFieldHolder().joinPointFactoryDec = factoryDec; 272 getStaticFieldHolder().getBody().add(0, factoryDec); 273 } 274 return getStaticFieldHolder().joinPointFactoryDec; 275 } 276 277 public Expr makeFactoryInstance() { 278 return getAST().makeGet(getFactoryDec()); 279 } 280 281 public Expr makeObjectsArray(Formals formals) { 282 final AST ast = getAST(); 283 284 Exprs exprs = ast.makeExprs(); 285 for (int i = 0; i < formals.size(); i++) { 286 exprs.add(ast.makeVar(formals.get(i))); 287 } 288 return ast.makeObjectArray(exprs); 289 } 290 291 public String makeString(int i) { 292 return Integer.toString(i, 16); 293 } 294 295 public String makeString(Type t) { 296 return t.getExternalName(); 297 } 298 299 public String makeString1(ASTObject ast, boolean asType) { 300 if (ast instanceof TypeD) { 301 return makeString(((TypeD) ast).getType()); 302 } else if (ast instanceof FormalDec) { 303 FormalDec formal = (FormalDec) ast; 304 if (asType) 305 return makeString(formal.getType()); 306 else 307 return formal.getId(); 308 } 309 return "?"; 310 } 311 312 public String makeString(TypeDs list) { 313 return makeString(list, true); 314 } 315 316 public String makeString(ASTObject list, boolean asType) { 317 if (list == null) 318 return ""; 319 StringBuffer buf = new StringBuffer (); 320 final int N = list.getChildCount(); 321 for (int i = 0; i < N; i++) { 322 buf.append(makeString1(list.getChildAt(i), asType)); 323 buf.append(':'); 324 } 325 return buf.toString(); 326 } 327 328 public Expr makeFactoryCall(String name, String stringRep) { 329 return getAST().makeCall( 331 makeFactoryInstance(), 332 name, 333 getAST().makeLiteral(stringRep)); 334 } 335 336 public Expr makeSignatureExpr(Dec dec) { 337 if (dec instanceof MethodDec) { 338 return makeSignatureExpr((MethodDec) dec); 339 } else if (dec instanceof ConstructorDec) { 340 return makeSignatureExpr((ConstructorDec) dec); 341 } else if (dec instanceof AdviceDec) { 342 return makeSignatureExpr((AdviceDec) dec); 343 } else if (dec instanceof FieldDec) { 344 return makeSignatureExpr((FieldDec) dec); 345 } else if (dec instanceof InitializerDec) { 346 return makeSignatureExpr((InitializerDec) dec); 347 } else { 348 return null; 349 } 350 } 351 352 public Expr makeSignatureExpr(ConstructorDec dec) { 353 StringBuffer buf = new StringBuffer (); 354 buf.append(makeString(dec.getModifiers().getValue())); 355 buf.append('-'); 356 buf.append('-'); 357 buf.append(makeString(dec.getDeclaringType())); 358 buf.append('-'); 359 buf.append(makeString(dec.getFormals(), true)); 360 buf.append('-'); 361 buf.append(makeString(dec.getFormals(), false)); 362 buf.append('-'); 363 buf.append(makeString(dec.getThrows())); 364 buf.append('-'); 365 return makeFactoryCall("makeConstructorSig", buf.toString()); 366 } 367 368 public Expr makeSignatureExpr(MethodDec dec) { 369 StringBuffer buf = new StringBuffer (); 370 buf.append(makeString(dec.getModifiers().getValue())); 371 buf.append('-'); 372 buf.append(dec.getName()); 373 buf.append('-'); 374 buf.append(makeString(dec.getDeclaringType())); 375 buf.append('-'); 376 buf.append(makeString(dec.getFormals(), true)); 377 buf.append('-'); 378 buf.append(makeString(dec.getFormals(), false)); 379 buf.append('-'); 380 buf.append(makeString(dec.getThrows())); 381 buf.append('-'); 382 buf.append(makeString(dec.getResultType())); 383 buf.append('-'); 384 return makeFactoryCall("makeMethodSig", buf.toString()); 385 } 386 387 public Expr makeSignatureExpr(AdviceDec dec) { 388 StringBuffer buf = new StringBuffer (); 389 buf.append(makeString(dec.getModifiers().getValue())); 390 buf.append('-'); 391 buf.append(dec.getName()); 392 buf.append('-'); 393 buf.append(makeString(dec.getDeclaringType())); 394 buf.append('-'); 395 buf.append(makeString(dec.getFormals(), true)); 396 buf.append('-'); 397 buf.append(makeString(dec.getFormals(), false)); 398 buf.append('-'); 399 buf.append(makeString(dec.getThrows())); 400 buf.append('-'); 401 buf.append(makeString(dec.getResultType())); 402 buf.append('-'); 403 return makeFactoryCall("makeAdviceSig", buf.toString()); 404 } 405 406 public Expr makeSignatureExpr(FieldDec dec) { 407 StringBuffer buf = new StringBuffer (); 408 buf.append(makeString(dec.getModifiers().getValue())); 409 buf.append('-'); 410 buf.append(dec.getName()); 411 buf.append('-'); 412 buf.append(makeString(dec.getDeclaringType())); 413 buf.append('-'); 414 buf.append(makeString(dec.getType())); 415 buf.append('-'); 416 return makeFactoryCall("makeFieldSig", buf.toString()); 417 } 418 419 public Expr makeSignatureExpr(InitializerDec dec) { 420 StringBuffer buf = new StringBuffer (); 421 buf.append(makeString(dec.getModifiers().getValue())); 422 buf.append('-'); 423 buf.append('-'); 424 buf.append(makeString(dec.getDeclaringType())); 425 buf.append('-'); 426 return makeFactoryCall("makeInitializerSig", buf.toString()); 427 } 428 429 public Expr makeSignatureExpr(CatchClause dec) { 430 StringBuffer buf = new StringBuffer (); 431 buf.append('-'); 432 buf.append('-'); 433 buf.append(makeString(dec.getDeclaringType())); 434 buf.append('-'); 435 buf.append(makeString(dec.getFormal().getType())); 436 buf.append('-'); 437 buf.append(dec.getFormal().getId()); 438 buf.append('-'); 439 return makeFactoryCall("makeCatchClauseSig", buf.toString()); 440 } 441 442 public Expr makeExecutingObjectExpr() { 443 Expr ret = makeThisExpr(); 444 if (ret == null) 445 ret = getAST().makeNull(); 446 return ret; 447 } 448 449 public JoinPoint getEnclosingExecutionJoinPoint() { 450 return null; 451 } 452 453 protected final Type getJoinPointType() { 454 return getTypeManager().getJoinPointType(); 455 } 456 457 protected final Type getJoinPointStaticPartType() { 458 return getTypeManager().getJoinPointStaticPartType(); 459 } 460 461 protected Expr makeSignatureExpr() { 462 return makeSignatureExpr(getTargetDec()); 463 } 464 protected final String getKindString() { 465 return getKind().toFullString(); 466 } 467 468 protected Expr makeStaticEnclosingExecutionJoinPointExpr() { 469 return null; 470 } 471 472 public final Expr makeStaticJoinPointExpr() { 473 final AST ast = getAST(); 474 475 Exprs args = 476 ast.makeExprs(ast.makeLiteral(getKindString()), makeSignatureExpr()); 477 478 ASTObject sourceLocation = getSourceLocation(); 479 if (sourceLocation == null) { 480 args.add(ast.makeNull()); 481 } else { 482 args.add(ast.makeLiteral(sourceLocation.getBeginLine())); 483 args.add(ast.makeLiteral(sourceLocation.getBeginColumn())); 484 } 485 486 return ast.makeCall(makeFactoryInstance(), "makeSJP", args); 487 } 488 489 private Expr reflectNull(Expr expr) { 490 if (expr == null) 491 return getAST().makeNull(); 492 else 493 return expr; 494 } 495 496 public final Expr makeDynamicJoinPointExpr() { 497 final AST ast = getAST(); 498 499 Exprs args = 500 ast.makeExprs( 501 makeStaticJoinPointVarExpr(), 502 reflectNull(makeThisExpr()), 503 reflectNull(makeTargetExpr()), 504 ast.makeObjectArray(makeArgsExprs())); 505 return ast.makeStaticCall(makeFactoryType(), "makeJP", args); 506 } 507 508 public Expr makeStaticEnclosingJoinPointVarExpr() { 509 if (getStaticEnclosingJoinPointDec() == null) { 510 return getAST().makeNull(); 511 } 512 return getAST().makeGet(getStaticEnclosingJoinPointDec()); 513 } 514 515 public Expr makeStaticJoinPointVarExpr() { 516 return getAST().makeGet(getStaticJoinPointDec()); 517 } 518 519 public Expr makeDynamicJoinPointVarExpr() { 520 return getAST().makeVar(getDynamicJoinPointDec()); 521 } 522 523 private boolean isSyntheticJoinPoint(Dec dec) { 524 if (dec.isSynthetic() && dec instanceof FieldDec) { 525 FieldDec field = (FieldDec) dec; 526 if (field.getId().indexOf("$ajcjp") != -1) 527 return true; 528 if (field.getId().startsWith("ajc$")) 529 return true; 530 } 531 return false; 532 } 533 534 public TypeDec getStaticFieldHolder() { 535 return getBytecodeType().getOutermostType().getTypeDec(); 536 } 537 538 FieldDec makeStaticFinalField(Type type, String name, Expr value) { 539 final AST ast = getAST(); 540 Modifiers modifiers = 541 ast.makeModifiers(Modifiers.FINAL | Modifiers.STATIC | Modifiers.PRIVATE); 542 if (getStaticFieldHolder().getType().isAspect()) 543 modifiers.setPublic(true); 544 if (getStaticFieldHolder().getType().isInterface()) 545 modifiers.setPublic(true); 546 FieldDec ret = ast.makeField(modifiers, type, name, value); 547 return ret; 549 } 550 551 void addStaticJoinPointDecToBody() { 552 if (staticJoinPointDec != null) { 553 staticJoinPointDec.setInitializer(makeStaticJoinPointExpr()); 554 Decs body = getStaticFieldHolder().getBody(); 555 int i = 0; 556 for (; i < body.size(); i++) { 557 if (!isSyntheticJoinPoint(body.get(i))) { 558 staticJoinPointDec.setId(staticJoinPointDec.getId() + i); 559 body.add(i, staticJoinPointDec); 560 break; 561 } 562 } 563 if (i == body.size()) 564 body.add(staticJoinPointDec); 565 } 566 } 567 568 public FieldDec getStaticJoinPointDec() { 569 if (staticJoinPointDec == null) { 570 String name = getAST().makeGeneratedName(getTargetDec().getId() + "$ajcjp"); 571 staticJoinPointDec = 572 makeStaticFinalField(getJoinPointStaticPartType(), name, null); 573 staticJoinPointDec.setAllEnclosingTypes(getStaticFieldHolder().getType()); 574 } 575 return staticJoinPointDec; 576 } 577 578 public VarDec getDynamicJoinPointDec() { 579 if (dynamicJoinPointDec == null) { 580 dynamicJoinPointDec = 581 getAST().makeFinalVar( 582 getJoinPointType(), 583 "thisJoinPoint", 584 makeDynamicJoinPointExpr()); 585 } 586 return dynamicJoinPointDec; 587 } 588 589 public FieldDec getStaticEnclosingJoinPointDec() { 590 if (getEnclosingExecutionJoinPoint() == null) { 591 return getStaticJoinPointDec(); 593 } 594 return getEnclosingExecutionJoinPoint().getStaticJoinPointDec(); 595 } 596 597 598 599 void showPrettyCircularityError(List plans) { 601 for (Iterator i = plans.iterator(); i.hasNext();) { 602 AdvicePlan plan = (AdvicePlan) i.next(); 603 AdviceDec adviceDec = plan.getAdviceDec(); 604 AspectDec aspectDec = plan.getAspectDec(); 605 606 if (adviceDec != null) { 607 getCompiler().showError( 608 adviceDec, 609 "circularity in advice precedence applied to " + this); 610 } else { 611 getCompiler().showError( 612 null, 613 plan + ": circularity in advice precedence applied to " + this); 614 } 615 } 616 } 617 618 public boolean hasPlans() { 619 return plans != null && plans.size() > 0; 620 } 621 622 public boolean plansMatch(JoinPoint other) { 624 if (plans.size() != other.plans.size()) 625 return false; 626 627 List otherPlans = new LinkedList(other.plans); 628 629 outer : for (Iterator i1 = plans.iterator(); i1.hasNext();) { 630 JpPlan plan1 = (JpPlan) i1.next(); 631 if (plan1 instanceof AdvicePlan) { 634 AdvicePlan advicePlan = (AdvicePlan)plan1; 635 if (advicePlan.getAdviceDec().needsCallSiteContext()) { 636 return false; 637 } 638 } 639 640 for (Iterator i2 = otherPlans.iterator(); i2.hasNext();) { 641 JpPlan plan2 = (JpPlan) i2.next(); 642 if (plan1.matches(plan2)) { 643 i2.remove(); 644 continue outer; 645 } 646 } 647 return false; 648 } 649 return true; 650 } 651 652 public void forgetPlans() { 653 plans = new ArrayList(0); 654 } 655 656 public void makeCorrespondences() { 657 if (plans == null) 658 return; 659 660 for (Iterator i = plans.iterator(); i.hasNext();) { 661 JpPlan plan = (JpPlan) i.next(); 662 if (plan instanceof AdvicePlan) { 663 AdviceDec adviceDec = ((AdvicePlan) plan).getAdviceDec(); 664 665 ASTObject codePoint = getTargetNode(); 666 667 ((AspectJCompiler) getCompiler()).getCorrespondences().addPointsTo( 670 adviceDec, 671 codePoint); 672 } 673 } 674 } 675 676 void sortPlans() { 677 if (plans.size() < 2) 678 return; 679 680 if (PartialOrder.sort(plans) == null) { 683 showPrettyCircularityError(plans); 684 } 685 } 686 687 public boolean needToImplement() { 688 return plans.size() != 0 689 || dynamicJoinPointDec != null 690 || staticJoinPointDec != null; 691 } 692 693 public void implementPlans() { 694 if (implementedPlans || !needToImplement()) return; 695 implementedPlans = true; 696 sortPlans(); 697 Collections.reverse(plans); 698 getCompiler().showMessage( 699 " implementing plans on " + this +System.identityHashCode(this)); 700 701 preImplement(); 702 if (!needToImplement()) return; 703 704 for (Iterator i = plans.iterator(); i.hasNext();) { 705 JpPlan plan = (JpPlan) i.next(); 706 plan.wrapJoinPoint(this); 707 } 708 makeCorrespondences(); 709 finishJoinPoint(); 710 } 711 712 protected void preImplement() { 713 } 714 715 716 public void finishJoinPoint() { 717 if (dynamicJoinPointDec != null) { 718 getStmts().add(0, dynamicJoinPointDec); 719 } 720 721 addStaticJoinPointDecToBody(); 722 } 723 724 public abstract Stmts getStmts(); 725 726 public abstract void setStmts(Stmts stmts); 727 } | Popular Tags |